Reputation: 2461
I am working with Canvas.drawArc()
in Android Studio and I have found the way to correctly draw the arc that I need, but I would like to know the coordinates of the Point()
which actually create the Arc
(not the edges but some of them in the middle). The code that I already have is:
Drawing the arc (works)
// 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);
}
The problem is that, since Canvas.drawArc()
is a void
method, I am not sure how could I get these coordinates.
Any suggestion? Indeed, I am not even interested in drawing the Arc
. I am just looking for a way to actually get those coordinates.
Maybe there is a way to create a curve within 3 points in java where I could get the coordinates. I would not mind using this method.
First approach
I have already tried to follow this answer but the values that I get are not the correct ones
// 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) );
2nd approach
I have also checked Path from Android, but I not aware if it is possible to use it. It seems that couple of methods (arcTo
and addArc
) could help, but I do not know how to attach it to the canvas, so I guess it is not possible to combine them.
3rd approach
After finding another previous answer, I have tried to implement it but the coordinates are again, wrong (not even close to my 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);
Upvotes: 10
Views: 2485
Reputation: 62831
Try the following using Path and PathMeasure.
This sample class draws on a custom view. The arc is drawn then twenty small circles are placed along the arc. You can divide the path into as many points as you like by dividing the path length. The array arcPoints will contain the selected points along the path.
If you don't want to draw the arc or the points, just delete the code that does the actual canvas drawing. The path will still be created and the points along the path captured.
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.
}
Upvotes: 7