android实现皮克定理
来源:互联网 发布:淘宝回收充值卡 编辑:程序博客网 时间:2024/04/30 15:53
废话少说代码备注很详细,直接上代码。
1.画图工具类
public class LogicView extends View { //背景点集合 private ArrayList<Circle> bgCircles; //所有线的集合 private ArrayList<Line> allLines; private Paint bgPaint; private Paint linePaint; public static final int LINE_TAG=1; public static final int MOVE_TAG=2; private int currOperateTag=LINE_TAG; public LogicView(Context context) { super(context); initData(); initView(); } public LogicView(Context context, AttributeSet attrs) { super(context, attrs); initData(); initView(); } private void initData() { bgCircles=new ArrayList<>(); allLines=new ArrayList<>(); } public ArrayList<Line> getAllLines() { return allLines; } private void initView() { bgPaint=new Paint(); bgPaint.setAntiAlias(true); bgPaint.setColor(Color.BLACK); linePaint=new Paint(); linePaint.setAntiAlias(true); linePaint.setStrokeWidth(2); linePaint.setColor(Color.RED); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //canvas.drawColor(Color.WHITE); canvas.drawColor(Color.argb(255,223,233,223)); for (int i=0;i<bgCircles.size();i++){ Circle circle=bgCircles.get(i); canvas.drawCircle(circle.getX(),circle.getY(),circle.getR(),bgPaint); } for (int i=0;i<allLines.size();i++){ Line line=allLines.get(i); canvas.drawLine(bgCircles.get(line.startCirclePosition).x,bgCircles.get(line.startCirclePosition).y, bgCircles.get(line.endCirclePosition).x,bgCircles.get(line.endCirclePosition).y,linePaint); } } /** * 画底部点 * author LH * date 2016/11/25 17:47 */ public void setBgCircle(ArrayList<Circle> bgCircles){ this.bgCircles=bgCircles; postInvalidate(); } /** * 清空画的线 * author LH * date 2016/11/25 18:45 */ public void clear() { allLines.clear(); tag=DOWN; currOperateTag=LINE_TAG; postInvalidate(); } /** * 整体放大或者缩小 * author LH * date 2016/11/28 10:02 * */ public void changeZoom(int row,float twoPointW,float twoPointH) { int centerPosition = getCenterNearPoint(); int centerRow = centerPosition / row; int centerLine = centerPosition % row; for (int i = 0; i < bgCircles.size(); i++) { int currentRow = i / row; int currentLine = i % row; bgCircles.get(i).x = bgCircles.get(centerPosition).x - (centerLine - currentLine) * twoPointW; bgCircles.get(i).y = bgCircles.get(centerPosition).y - (centerRow - currentRow) * twoPointH; } Log.e("allLines", allLines.toString()); postInvalidate(); } /** * 设置当前的操作 * author LH * date 2016/11/25 18:52 */ public void setCurrOperateTag(int currOperateTag) { this.currOperateTag = currOperateTag; } /** * 画移动时的临时直线 * author LH * date 2016/11/25 20:07 */ public void drawMoveLine(Line line){ if(tag==DOWN){ allLines.add(line); }else { allLines.set(allLines.size() - 1,line); } postInvalidate(); } /** * 求两点之间的距离 * author LH * date 2016/11/25 17:06 */ private float twoPointW(float moveX,float moveY,float toX,float toY){ return (float) Math.sqrt(Math.pow(moveX-toX,2)+Math.pow(moveY-toY,2)); } /** * 获取距离目标点最近的点的位置 * author LH * date 2016/11/25 17:32 */ private int getNearestCircle(float moveX,float moveY){ int point=0; float near=twoPointW(moveX,moveY,bgCircles.get(0).x,bgCircles.get(0).y); for (int i=0;i<bgCircles.size();i++){ float currentW=twoPointW(moveX,moveY,bgCircles.get(i).x,bgCircles.get(i).y); if(near>currentW){ near=currentW; point=i; } } return point; } /** * 获取画线的中心点的相近的点 * author LH * date 2016/11/28 10:44 * @return 点的位置 */ public int getCenterNearPoint(){ if(allLines.size()>0) { float nearX = bgCircles.get(allLines.get(0).startCirclePosition).x; float nearY = bgCircles.get(allLines.get(0).startCirclePosition).y; float farX = bgCircles.get(allLines.get(0).startCirclePosition).x; float farY = bgCircles.get(allLines.get(0).startCirclePosition).y; for (int i = 0; i < allLines.size(); i++) { Line line = allLines.get(i); if (nearX > bgCircles.get(line.startCirclePosition).x) { nearX = bgCircles.get(line.startCirclePosition).x; } if (nearX > bgCircles.get(line.endCirclePosition).x) { nearX = bgCircles.get(line.endCirclePosition).x; } if (nearY > bgCircles.get(line.startCirclePosition).y) { nearY = bgCircles.get(line.startCirclePosition).y; } if (nearY > bgCircles.get(line.endCirclePosition).y) { nearY = bgCircles.get(line.endCirclePosition).y; } if (farX < bgCircles.get(line.startCirclePosition).x) { farX = bgCircles.get(line.startCirclePosition).x; } if (farX < bgCircles.get(line.endCirclePosition).x) { farX = bgCircles.get(line.endCirclePosition).x; } if (farY < bgCircles.get(line.startCirclePosition).y) { farY = bgCircles.get(line.startCirclePosition).y; } if (farY < bgCircles.get(line.endCirclePosition).y) { farY = bgCircles.get(line.endCirclePosition).y; } } float centerX = (nearX + farX) / 2; float centerY = (nearY + farY) / 2; return getNearestCircle(centerX, centerY); }else { return bgCircles.size()/2; } } @Override public boolean onTouchEvent(MotionEvent event) { switch (currOperateTag) { case LINE_TAG: lineOperate(event); break; case MOVE_TAG: if(allLines.size()>0) { moveOperate(event); } break; } return true; } ArrayList<LinePoint> linePoints; int down_nearPoint,up_nearPoint,move_nearPoint; private void moveOperate(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: float x_down = event.getRawX(); float y_down = event.getRawY(); down_nearPoint = getNearestLinePoints(x_down,y_down); Log.e("getNearestLinePoints",linePoints.toString()); break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: float x_move = event.getRawX(); float y_move = event.getRawY(); move_nearPoint = getNearestCircle(x_move, y_move); drawMoveLinePoint(move_nearPoint); break; } } /** * 画拖动时的直线 * author LH * date 2016/11/26 15:54 */ private void drawMoveLinePoint(int move_nearPoint) { for(int i=0;i<linePoints.size();i++){ LinePoint linePoint=linePoints.get(i); Line addLine; if(linePoint.type==0){ addLine=new Line(move_nearPoint,linePoint.line.endCirclePosition); }else { addLine=new Line(linePoint.line.startCirclePosition,move_nearPoint); } allLines.set(linePoint.position,addLine); } postInvalidate(); } /** * 获取拉伸是距离点击点最近的直线 * author LH * date 2016/11/26 10:50 */ private int getNearestLinePoints(float x_down, float y_down) { linePoints=new ArrayList<>(); int position=allLines.get(0).startCirclePosition; float near=twoPointW(x_down,y_down,bgCircles.get(allLines.get(0).startCirclePosition).x,bgCircles.get(allLines.get(0).startCirclePosition).y); for (int i=0;i<allLines.size();i++){ float currentStart=twoPointW(x_down,y_down,bgCircles.get(allLines.get(i).startCirclePosition).x,bgCircles.get(allLines.get(i).startCirclePosition).y); float currentEnd=twoPointW(x_down,y_down,bgCircles.get(allLines.get(i).endCirclePosition).x,bgCircles.get(allLines.get(i).endCirclePosition).y); if (near>currentStart){ near=currentStart; position=allLines.get(i).startCirclePosition; } if (near>currentEnd){ near=currentEnd; position=allLines.get(i).endCirclePosition; } } for (int i=0;i<allLines.size();i++){ if(allLines.get(i).startCirclePosition==position){ LinePoint linePoint=new LinePoint(0,i,allLines.get(i)); linePoints.add(linePoint); }else if(allLines.get(i).endCirclePosition==position){ LinePoint linePoint=new LinePoint(1,i,allLines.get(i)); linePoints.add(linePoint); } } return position; } float x_down,y_down,x_up,y_up; int tag=1; int DOWN=1,MOVE=2; private void lineOperate(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: x_down = event.getRawX(); y_down = event.getRawY(); down_nearPoint = getNearestCircle(x_down, y_down); tag=DOWN; break; case MotionEvent.ACTION_UP: x_up = event.getRawX(); y_up = event.getRawY(); up_nearPoint = getNearestCircle(x_up, y_up); break; case MotionEvent.ACTION_MOVE: float x_move = event.getRawX(); float y_move = event.getRawY(); move_nearPoint = getNearestCircle(x_move, y_move); drawMoveLine(new Line(down_nearPoint, move_nearPoint)); tag=MOVE; break; } }}2.调用主函数
public class MainActivity extends Activity { @Bind(R.id.logicView) LogicView logicView; @Bind(R.id.btn_line) ImageView btnLine; @Bind(R.id.btn_move) ImageView btnMove; @Bind(R.id.btn_zoomIn) ImageView btnZoomIn; @Bind(R.id.btn_zoomOut) ImageView btnZoomOut; @Bind(R.id.btn_clean) ImageView btnClean; @Bind(R.id.activity_main) RelativeLayout activityMain; private ArrayList<Circle> bgCircles; private float rightBtnW = 150;//右侧按钮宽度 private float bottomH = 20;//底部宽度 private int bgPointRow = 24;//背景的行数 private int bgPointLine = 15;//背景的列数 float useW,useH; private double allZooms[]=new double[]{1.2,1.5,1.8,2.0,2.2,2.5,2.8,3.0}; private int currentZoom=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); ButterKnife.bind(this); btnLine.setSelected(true); btnMove.setSelected(false); getBgCirclePosition(); logicView.setBgCircle(bgCircles); } /** * 设置背景圆的坐标和半径 * author LH * date 2016/11/25 16:06 */ private void getBgCirclePosition() { bgCircles = new ArrayList<>(); WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); int width = wm.getDefaultDisplay().getWidth(); int height = wm.getDefaultDisplay().getHeight(); Log.e("position", "width:" + width + " height:" + height); useW = width - rightBtnW; useH = height - bottomH; for (int j = 0; j < bgPointLine; j++) { for (int i = 0; i < bgPointRow; i++) { Circle circle = new Circle(useW / (bgPointRow + 1) * (i + 1), useH / (bgPointLine + 1) * (j + 1), 5); bgCircles.add(circle); } } } @OnClick({R.id.btn_line, R.id.btn_move, R.id.btn_zoomIn, R.id.btn_zoomOut, R.id.btn_clean}) public void onClick(View view) { switch (view.getId()) { case R.id.btn_line: btnLine.setSelected(true); btnMove.setSelected(false); logicView.setCurrOperateTag(LogicView.LINE_TAG); break; case R.id.btn_move: btnLine.setSelected(false); btnMove.setSelected(true); logicView.setCurrOperateTag(LogicView.MOVE_TAG); break; case R.id.btn_zoomIn: if(currentZoom<allZooms.length-1) { currentZoom++; logicView.changeZoom(bgPointRow, (float) (useW / (bgPointRow + 1) * allZooms[currentZoom]), (float) (useH / (bgPointLine + 1) * allZooms[currentZoom])); } break; case R.id.btn_zoomOut: if(currentZoom>0) { currentZoom--; logicView.changeZoom(bgPointRow, (float) (useW / (bgPointRow + 1) * allZooms[currentZoom]), (float) (useH / (bgPointLine + 1) * allZooms[currentZoom])); } break; case R.id.btn_clean: btnLine.setSelected(true); btnMove.setSelected(false); logicView.setCurrOperateTag(LogicView.LINE_TAG); currentZoom=0; getBgCirclePosition(); logicView.setBgCircle(bgCircles); logicView.clear(); break; } }}
3.用到的实体类
/** * Created by LH on 2016/11/25. */public class Circle { float x; float y; float r; public Circle(float x, float y, float r) { this.x = x; this.y = y; this.r = r; } public float getX() { return x; } public float getY() { return y; } public float getR() { return r; }}
/** * Created by LH on 2016/11/25. */public class Line { //起始的点的位置 int startCirclePosition; //终止点的位置 int endCirclePosition; public Line(int startCirclePosition, int endCirclePosition) { this.startCirclePosition = startCirclePosition; this.endCirclePosition = endCirclePosition; } @Override public String toString() { return "Line{" + "startCirclePosition=" + startCirclePosition + ", endCirclePosition=" + endCirclePosition + '}'; }}
/** * Created by LH on 2016/11/26. */public class LinePoint { //0起点 1终点 int type; //直线在集合中的位置 int position; //直线 Line line; public LinePoint(int type, int position, Line line) { this.type = type; this.position = position; this.line = line; } @Override public String toString() { return "LinePoint{" + "type=" + type + ", position=" + position + ", line=" + line + '}'; }}
4.布局文件
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.lh.pointpicture.MainActivity"> <RelativeLayout android:id="@+id/rl_control" android:layout_width="150px" android:layout_height="match_parent" android:layout_alignParentRight="true" android:background="#606060"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_centerVertical="true" android:layout_centerHorizontal="true" android:gravity="center_horizontal"> <ImageView android:id="@+id/btn_line" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/zhixian_selector"/> <ImageView android:id="@+id/btn_move" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:background="@drawable/yidong_selector"/> <ImageView android:id="@+id/btn_zoomIn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:background="@drawable/fangda_selector"/> <ImageView android:id="@+id/btn_zoomOut" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:background="@drawable/suoxia_selector"/> <ImageView android:id="@+id/btn_clean" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:background="@drawable/chongzuo_selector"/> </LinearLayout> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_toLeftOf="@id/rl_control"> <com.example.lh.pointpicture.LogicView android:id="@+id/logicView" android:layout_width="1130px" android:layout_height="800px" android:layout_centerInParent="true" android:clickable="true"/> </RelativeLayout></RelativeLayout>
0 0
- android实现皮克定理
- 皮克定理
- 皮克定理
- 皮克定理 poj2954
- poj1265皮克定理
- 皮克定理
- 皮克定理
- 皮克定理
- 皮克定理
- usaco 3.4 Electric Fence 皮克定理
- 2261: Triangle (皮克定理)
- [U]3.4.3 皮克定理
- 欧几里德算法与皮克定理
- POJ 1265 Area (皮克定理)
- NOJ 1434 Fence (皮克定理)
- POJ 2954 Triangle (皮克定理)
- POJ 1265 Area (皮克定理)
- poj 1265 Area(几何 皮克定理 )
- Net中时间格式化的几种方式
- Fortran指针再探
- 零基础从头学习Swift(一):Swift环境搭建
- 最详细的Log4j使用教程
- 关于Vitamio花屏问题(继Vitamio使用方法)
- android实现皮克定理
- android--Service自动重启而不被kill掉的一些方法
- Requirejs高级应用(三):同步加载
- 关于Cookie中的Path和domain
- C# 类库读取app.config
- struts2项目启动报错com.opensymphony.xwork2.config.ConfigurationException: Unable to load configuration.
- lxml学习笔记
- PHP多线程扩展pthreads实例
- rocketmq介绍及安装过程