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
原创粉丝点击