Android - calculate arc angle

I have an arc and I want to draw scale marks at 0, 45, 90, 135, 180 degrees, can someone help me with the math needed to achieve the x, y points of 5 and 30 on this sketch ?:

enter image description here

here is my code for drawing a scale mark 1.

   private void drawScale(Canvas canvas) {
        //canvas.drawOval(scaleRect, scalePaint);

        canvas.save();

        Paint p = new Paint();
        p.setColor(Color.WHITE);
        p.setStrokeWidth(10f);
        canvas.drawLine(rectF.left-getWidth()/20, rectF.height()/2, rectF.left, rectF.height()/2, p);


    canvas.restore();
}
+4
source share
2 answers

You can calculate its rotation with sinand cos. Suppose you have a zero point Aand you want to rotate it to a point Bthat rotates 30 Β°. Something like that:

enter image description here

Basically a new point is located at (cx+x,cy+y). In this particular case, the following definition sinand coswill be as follows:

sin = x/R
cos = y/R

x y. :

x = cx + sin(angle) * R; 
y = cy + cos(angle) * R;

Android Canvas!

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();
    float cx = getWidth() / 2f;
    float cy = getHeight() / 2f;

    float scaleMarkSize = getResources().getDisplayMetrics().density * 16; // 16dp
    float radius = Math.min(getWidth(), getHeight()) / 2;

    for (int i = 0; i < 360; i += 45) {
        float angle = (float) Math.toRadians(i); // Need to convert to radians first

        float startX = (float) (cx + radius * Math.sin(angle));
        float startY = (float) (cy - radius * Math.cos(angle));

        float stopX = (float) (cx + (radius - scaleMarkSize) * Math.sin(angle));
        float stopY = (float) (cy - (radius - scaleMarkSize) * Math.cos(angle));

        canvas.drawLine(startX, startY, stopX, stopY, scalePaint);
    }

    canvas.restore();
}

45 Β°. , , Y , . :

enter image description here

+11

, , .

  • 0 deg β†’ (-1,0)
  • 45 β†’ (-1/sqrt (2), (1/sqrt (2))
  • 90 β†’ (0,1)
  • 135 deg β†’ (1/sqrt (2), (1/sqrt (2))
  • 180 β†’ (1,0)

,

point = center + (unit vector * distance from center)

, andrew.

private static final float RADIUS = 400.0f;
private static final float MARK_LENGTH = 30.0f;
private static final UnitVector[] UNIT_VECTORS = new UnitVector[] {
        new UnitVector(-1,0), // 0 deg
        new UnitVector((float) (-1/Math.sqrt(2)), (float) (1/Math.sqrt(2))), // 45 deg
        new UnitVector(0, 1), // 90 deg
        new UnitVector((float) (1/Math.sqrt(2)), (float) (1/Math.sqrt(2))), // 135 deg
        new UnitVector(1, 0), // 180 deg
        new UnitVector((float) (1/Math.sqrt(2)), (float) (-1/Math.sqrt(2))), // 225 deg
        new UnitVector(0, -1), // 270 deg
        new UnitVector((float) (-1/Math.sqrt(2)), (float) (-1/Math.sqrt(2))), // 315 deg
};

static class UnitVector {
    final float x;
    final float y;

    UnitVector(final float x, final float y) {
        this.x = x;
        this.y = y;
    }
}

// Call this from onDraw
public void drawMarks(final Canvas canvas) {
    for (final UnitVector unitVector : UNIT_VECTORS) {
        this.drawMarkWithVector(unitVector, canvas);
    }
}

private void drawMarkWithVector(final UnitVector unitVector, final Canvas canvas) {
    final float centerPointX = this.getWidth() / 2;
    final float centerPointY = this.getHeight() / 2;
    final float startX = centerPointX + (unitVector.x * RADIUS);
    final float startY = centerPointY + (unitVector.y * RADIUS);
    final float endX = centerPointX + (unitVector.x * (RADIUS + MARK_LENGTH));
    final float endY = centerPointY + (unitVector.y * (RADIUS + MARK_LENGTH));
    canvas.drawLine(startX, startY, endX, endY, this.paint);
}

Result of the code

+4

All Articles