【问题标题】:calculate the area of shape created by custom lines on canvas in android计算android中画布上自定义线条创建的形状面积
【发布时间】:2017-07-06 12:47:35
【问题描述】:

我正在制作一个用于架构规划的应用程序。在那,我想通过 drawline() 方法在画布上找到由线条绘制的封闭形状所覆盖的区域。这是守则。

public class CanvasBackground extends View {

public static boolean addPath;
public static flg flag;
public static boolean addLine = false;
public static boolean join = false;
public static boolean isDrawing;
public static int myLine;
public static ArrayList<Line> lines = new ArrayList<>();
public static ArrayList<Path> paths = new ArrayList<>();
public Paint paint;
public Context context;
public Canvas canvas;
public ScaleGestureDetector scaleGestureDetector;
public Bitmap addBtnBitmap;
public int passed_size;
float scalfactor = 1f;
Button addBtn;
public CanvasBackground(Context context) {
    super(context);
    this.context = context;
    paint = new Paint();
    scaleGestureDetector = new ScaleGestureDetector(context, new CanvasScale());
    DrawingActivity drawingActivity = new DrawingActivity();
    passed_size = drawingActivity.getCategory();


    setDrawingCacheEnabled(true);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    this.canvas = canvas;
    canvas.save();
    //add Button Select

    paint.setColor(Color.WHITE);
    canvas.drawPaint(paint);

    DrawingZoomingCanvas(canvas);
    DrawingLine(canvas);


    canvas.restore();
    Log.e("OnDraw >>>", "CALLING");
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (addLine) {
                if (lines.size() != 0) {
                    Line current = lines.get(lines.size() - 1);

                    lines.add(new Line(current.stopX, current.stopY, myLine));


                } else {

                    lines.add(new Line(event.getX(), event.getY(), myLine));
                }


                isDrawing = true;
                addLine = false;
            }

            if (addPath) {
                Path path = new Path();
                path.moveTo(event.getX(), event.getY());
                paths.add(path);
                isDrawing = true;
                addPath = false;
            }
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            if (isDrawing) {
                if (lines.size() > 0 && flg.ADDLINE == flag) {
                    Line current = lines.get(lines.size() - 1);
                    current.stopX = event.getX();
                    current.stopY = event.getY();
                } else if (paths.size() > 0 && flg.ADDPATH == flag) {
                    Path path = paths.get(paths.size() - 1);
                    path.lineTo(event.getX(), event.getY());
                }
                invalidate();
            }
            break;
        case MotionEvent.ACTION_UP:
            if (isDrawing) {
                if (lines.size() > 0 && flg.ADDLINE == flag) {
                    Line current = lines.get(lines.size() - 1);
                    current.stopX = event.getX();
                    current.stopY = event.getY();
                }
                invalidate();
            }
            break;
        default:
            break;
    }
    //scaleGestureDetector.onTouchEvent(event);

    Log.e("OnTouch >>>", "CALLING " + isDrawing + " >> " + event.getX() + " >> " + event.getY() + ">>" + event.getAction());
    return true;
}

//drawing a line
private void DrawingLine(Canvas canvas) {
    paint = new Paint();
    paint.setColor(Color.RED);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(2);
    paint.setAntiAlias(true);
    for (Line l : lines) {
        canvas.drawLine(l.startX, l.startY, l.stopX, l.stopY, paint);
        canvas.drawText(String.valueOf(l.getSize()), l.startX, l.startY, paint);
    }
    for (Path l : paths) {
        canvas.drawPath(l, paint);
    }
    if (flg.JOIN == flag) {
        Line first = lines.get(0);
        Line last = lines.get(lines.size() - 1);
        Log.e("FL", "First:-" + first.startX + first.startY + "Last" + last.stopX + last.stopY);
        canvas.drawLine(first.startX, first.startY, last.stopX, last.stopY, paint);
        canvas.drawText(String.valueOf(myLine), last.stopX, last.stopY, paint);
        invalidate();
        isDrawing = true;

    }
    setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.e("CALL CLICK", "vv" + v.getId());
        }
    });

}

//drawing Matrix Canvas With Zoom
private void DrawingZoomingCanvas(Canvas canvas) {
    //drawing Matarix
    canvas.translate(scalfactor * 10, scalfactor * 10);
    canvas.scale(scalfactor, scalfactor);
    paint.setColor(Color.rgb(220, 220, 220));
    for (int i = 0; i <= canvas.getHeight() * scalfactor; i += 10) {
        canvas.drawLine(i, 0, i, canvas.getHeight(), paint);
        canvas.drawLine(0, i, canvas.getWidth(), i, paint);
    }
}

public void join_line() {

    Line first = lines.get(0);
    Line last = lines.get(lines.size() - 1);
    Log.e("FL", "First:-" + first.startX + first.startY + "Last" + last.stopX + last.stopY);
    canvas.drawLine(first.startX, first.startY, last.stopX, last.stopY, paint);
    invalidate();
    isDrawing = true;

}

public enum flg {ADDLINE, ADDPATH, JOIN}

private class CanvasScale extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        scalfactor *= scaleGestureDetector.getScaleFactor();
        scalfactor = Math.max(0.1f, Math.min(scalfactor, 10.0f));
        invalidate();
        return true;
    }
}

}

这是活动。

public class DrawingActivity extends AppCompatActivity {
public int line_size;
CanvasBackground canvasBackground;
LinearLayout linearLayoutV, linearLayoutH;
Button addBtn, confirmBtn, clearBtn, addPath, joinbtn;
Context context = DrawingActivity.this;
LinearLayout.LayoutParams wrap_content_layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    canvasBackground = new CanvasBackground(context);

    //Main Layout Liner
    linearLayoutV = new LinearLayout(context);
    linearLayoutV.setOrientation(LinearLayout.VERTICAL);

    linearLayoutH = new LinearLayout(context);
    linearLayoutH.setOrientation(LinearLayout.HORIZONTAL);
    linearLayoutH.setWeightSum(4);
    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(10, ViewGroup.LayoutParams.WRAP_CONTENT);
    layoutParams.weight = 1;


    //add Line Button
    addBtn = new Button(context);
    addBtn.setLayoutParams(layoutParams);
    addBtn.setText("Line+");
    addBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            CanvasBackground.addLine = true;
            CanvasBackground.flag = CanvasBackground.flg.ADDLINE;

            //**************** SET LENGTH
            AlertDialog.Builder builder1 = new AlertDialog.Builder(context);
            builder1.setMessage("Set the length of line");
            builder1.setCancelable(true);
            final EditText input = new EditText(DrawingActivity.this);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT);
            input.setLayoutParams(lp);
            builder1.setView(input);

            builder1.setPositiveButton(
                    "Done",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            line_size = Integer.parseInt(input.getText().toString());
                            Log.e("size", String.valueOf(getCategory()));
                            CanvasBackground.myLine = line_size;
                            dialog.cancel();
                        }
                    });

            builder1.setNegativeButton(
                    "Cancel",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                        }
                    });

            AlertDialog alert11 = builder1.create();
            alert11.show();
        }
    });
    linearLayoutH.addView(addBtn);
    // join last button
    joinbtn = new Button(context);
    joinbtn.setLayoutParams(layoutParams);
    joinbtn.setText("Join");
    joinbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            CanvasBackground.flag = CanvasBackground.flg.JOIN;

            v.invalidate();
            //**************** SET LENGTH
            AlertDialog.Builder builder1 = new AlertDialog.Builder(context);
            builder1.setMessage("Set the length of line");
            builder1.setCancelable(true);
            final EditText input = new EditText(DrawingActivity.this);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT);
            input.setLayoutParams(lp);
            builder1.setView(input);

            builder1.setPositiveButton(
                    "Done",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            line_size = Integer.parseInt(input.getText().toString());
                            Log.e("size", String.valueOf(getCategory()));
                            CanvasBackground.myLine = line_size;
                            dialog.cancel();
                        }
                    });

            builder1.setNegativeButton(
                    "Cancel",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                        }
                    });

            AlertDialog alert11 = builder1.create();
            alert11.show();

        }
    });
    linearLayoutH.addView(joinbtn);

    //add Line Button
    addPath = new Button(context);
    addPath.setLayoutParams(layoutParams);
    addPath.setText("Path+");
    addPath.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            CanvasBackground.addPath = true;
            CanvasBackground.flag = CanvasBackground.flg.ADDPATH;
        }
    });
    linearLayoutH.addView(addPath);



    //add Confirm Button
    confirmBtn = new Button(context);
    confirmBtn.setLayoutParams(layoutParams);
    confirmBtn.setText("Ok");
    confirmBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            CanvasBackground.isDrawing = false;
        }
    });
    linearLayoutH.addView(confirmBtn);
    linearLayoutV.addView(linearLayoutH);


    linearLayoutV.addView(canvasBackground);

    setContentView(linearLayoutV);
}

public int getCategory() {
    return line_size;
}

}

这是整个代码。请帮帮我。

【问题讨论】:

  • 你知道计算图形面积的公式吗?如果你这样做 - 将其转换为 Java。如果没有 - 先找到它,然后再转换。
  • 您也可以使用搜索找到现成的解决方案。
  • 你是绝对正确的。但不固定绘制哪种形状。
  • 任何形状都有通用公式

标签: android performance android-layout canvas


【解决方案1】:

你可以首先通过观察开始和结束坐标来验证用户在触摸时形成的形状是否接近。一次,如果形状是封闭的。它形成一个正多边形。

对于正多边形。

  1. 求多边形的周长(permiter = 所有边长的总和)

  2. 然后找到多边形的 apothem (apothem = 边长 / 2tan(180/边数))

  3. 他们使用周长和 apothem 找到面积。(面积 =(面积 * 周长)/2)

另请参阅此链接以获取有关详细步骤的更多信息。 http://www.wikihow.com/Find-the-Area-of-Regular-Polygons

【讨论】:

  • 欢迎 The Kishan.. 如果您觉得此答案有用。请为这个答案投票。
猜你喜欢
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2019-03-03
  • 1970-01-01
  • 2023-02-21
相关资源
最近更新 更多