【问题标题】:Get coordinates from a drawn arc in a canvas从画布中绘制的弧线获取坐标
【发布时间】:2020-02-24 08:13:12
【问题描述】:

我正在与Android Studio 中的Canvas.drawArc() 合作,我已经找到了正确绘制我需要的弧线的方法,但我想知道Point() 的坐标,它实际上创建了Arc(不是边缘,而是其中一些在中间)。我已经拥有的代码是:

画弧线(作品)

// Set the arc of movement of the encoder
public void setArc(Canvas canvas, Point startPoint, Point endPoint){
    Point centerArc = new Point((int) centerX, (int) centerY);
    Point leftEdge = new Point(startPoint.x, startPoint.y);
    Point rightEdge = new Point(endPoint.x, endPoint.y);

    int radiusArc = (int) Math.sqrt((leftEdge.x - centerArc.x)*(leftEdge.x - centerArc.x) + (leftEdge.y - centerArc.y)*(leftEdge.y - centerArc.y));

    int startAngle = (int) (190/Math.PI*atan2(leftEdge.y-centerArc.y, leftEdge.x-centerArc.x));
    int endAngle = (int) (210/Math.PI*atan2(rightEdge.y-centerArc.y, rightEdge.x-centerArc.y));

    RectF rect = new RectF(centerX - radiusArc, centerY - radiusArc, centerX + radiusArc, centerY + radiusArc);
    canvas.drawArc(rect, startAngle, endAngle, true, mRectPaint);
}

问题在于,由于Canvas.drawArc()void 方法,我不确定如何获得这些坐标。

有什么建议吗?事实上,我什至对绘制Arc 都不感兴趣。我只是在寻找一种方法来实际获取这些坐标。

也许有一种方法可以在 java 中的 3 个点内创建一条曲线,我可以获得坐标。我不介意使用这种方法。

第一种方法

我已经尝试关注这个answer,但我得到的值不是正确的

//  Calculate the coordinates of 100 points of the arc
    Point[] coordinatesArc = new Point[100];
    coordinatesArc[0] = startPoint;
    Point coordinate = new Point();
    int xCoordinate;
    int yCoordinate;
    for (int i = 1; i<=98; i++){
        xCoordinate = startPoint.x + radiusArc*(int)Math.sin(i);
        yCoordinate = startPoint.y - radiusArc*(1-(int)Math.cos(i));
        coordinate.set(xCoordinate, yCoordinate);
        coordinatesArc[i]=coordinate;
    }
    coordinatesArc[99]= endPoint;
    Log.d(TAG, "Values: x = " + String.valueOf(coordinatesArc[97].x) + " y = " + String.valueOf(coordinatesArc[97].y) );

第二种方法

我还检查了来自 Android 的 Path,但我不知道是否可以使用它。似乎有两种方法(arcToaddArc)可以提供帮助,但我不知道如何将它附加到画布上,所以我想不可能将它们结合起来。

第三种方法

在找到另一个以前的answer 后,我尝试实现它,但坐标再次错误(甚至不接近我的endPoint)。

Point centerArc = new Point((int) centerX, (int) centerY);
    Point leftEdge = new Point(startPoint.x, startPoint.y);
    int radiusArc = (int) Math.sqrt((leftEdge.x - centerArc.x)*(leftEdge.x - centerArc.x) + (leftEdge.y - centerArc.y)*(leftEdge.y - centerArc.y));
    int startAngle = (int) (190/Math.PI*atan2(leftEdge.y-centerArc.y, leftEdge.x-centerArc.x));

    Point[] coordinatesArc = new Point[100];
    Point auxPoint = new Point();
    coordinatesArc[0] = startPoint;
    for(int i = 1; i<=98;i++){
        auxPoint.x = (int) (centerX + radiusArc * Math.cos(startAngle + i));
        auxPoint.y = (int) (centerY + radiusArc * Math.sin(startAngle + i));
        coordinatesArc[i]= auxPoint;
    }
    coordinatesArc[99]= endPoint;
    Log.d(TAG, "COORDINATES ARC: x =  " + coordinatesArc[98].x  + " & y = " + coordinatesArc[98].y);

【问题讨论】:

  • 也许这会对你有所帮助:stackoverflow.com/questions/25935315/…
  • 我更愿意将弧线分割成 100 个点,而不是检查一个点是否是弧线的一部分。不知道有没有可能?

标签: java android canvas


【解决方案1】:

使用PathPathMeasure 尝试以下操作。

此示例类使用自定义视图。画出弧线,然后沿弧线放置二十个小圆圈。您可以通过划分路径长度将路径划分为任意数量的点。 arcPoints 数组将包含沿路径选择的点。

如果您不想绘制圆弧或点,只需删除执行实际画布绘制的代码即可。仍将创建路径并捕获沿路径的点。

MyView.java

 final Path mPath = new Path();

    int startAngle = (int) (190/Math.PI*atan2(startPoint.y-centerY, startPoint.x-centerX));
    int sweepAngle = (int) (210/Math.PI*atan2(endPoint.y-centerY, endPoint.x-centerX));
    int radiusArc = (int) Math.sqrt((startPoint.x - centerX)*(startPoint.x - centerX) + (startPoint.y - centerY)*(startPoint.y - centerY));

    final RectF oval = new RectF(centerX - radiusArc, centerY - radiusArc, centerX + radiusArc, centerY + radiusArc);

    mPath.addArc(oval, startAngle, sweepAngle);

    PathMeasure pm = new PathMeasure(mPath, false);
    float[] xyCoordinate = {startPoint.x, startPoint.y};
    float pathLength = pm.getLength();

    // Capture the points along the arc.
    PointF[] arcPoints = new PointF[20];
    for (int i = 0; i < 20; i++) {
        pm.getPosTan(pathLength * i / 19, xyCoordinate, null);
        arcPoints[i] = new PointF(xyCoordinate[0], xyCoordinate[1]);
    }

    Log.d(TAG, Arrays.toString(arcPoints));
    // Do drawing just to show the code works. Delete if drawing is not needed.
    canvas.drawPath(mPath, mRectPaint);
    for (int i = 0; i < 20; i++) {
        Log.d(TAG, String.format("Point #%d = (%.0f,%.0f)", i + 1, xyCoordinate[0], xyCoordinate[1]));
        canvas.drawCircle(arcPoints[i].x, arcPoints[i].y, 10, mTracerPaint); // Radius of the coordinate circle drawn.
    }

【讨论】:

  • 嗨,我正在尝试在我的项目中实施您的解决方案,但我无法使其工作。它基本上在我的画布上用蓝色绘制了非常大的区域,而不是红线。我将在我完成的代码中上传解决方案。我相信 xyCoordinates 是我的 startPoint 的坐标 x 和 y。我错了吗?
  • 顺便说一句,这段代码没有给我点的坐标,它只是在画布上绘制它们。这不是我要找的
  • @Mario 如果删除canvas.drawPath() 语句,代码将不会在画布上绘制路径,但仍会创建路径。 xyCoordinates 将包含沿曲线的点,但您需要在 for 循环中捕获它们。您看到的蓝色斑点是因为您正在使用半径来绘制示踪圆。如果您只使用一些值,例如“5”,您应该会看到我发布的内容。无论如何,所有的绘图只是为了证明代码有效。您只需要在 for 循环中捕获该点,而无需进行任何绘图。
  • 嗨。我会在几个小时后或星期一看看(取决于我什么时候完成其他事情)。但感谢您的更新。我会尽快看看
  • @Mario Here 是完整的 MyView 类的要点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
相关资源
最近更新 更多