Ziv Kesten Ziv Kesten - 1 year ago 86
Android Question

Android - calculate arc angle

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

enter image description here

here is my code for drawing the 1 scale mark.

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


Paint p = new Paint();
canvas.drawLine(rectF.left-getWidth()/20, rectF.height()/2, rectF.left, rectF.height()/2, p);


Answer Source

You can calculate its rotation using sin and cos. Lets assume that you have zero point A and want to rotate it to point B which is rotated for 30°. Something like this:

enter image description here

Basically new point is at (cx+x,cy+y). In this particular case definition of sin and cos would be next:

sin = x/R
cos = y/R

It is not hard to get exact x and y. So to rotate point on particular angle in circle with know radius we need to calculate coordinates in next way:

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

Now lets get back to Android and Canvas!

protected void onDraw(Canvas canvas) {

    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);


Code will draw marks with step of 45°. Note you need to convert angle to radians and for Y axis I used minus cause on canvas it is flipped. Here is what I have got:

enter image description here