Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

        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();
}
like image 663
Ziv Kesten Avatar asked May 03 '15 13:05

Ziv Kesten


People also ask

What is the formula for calculating arc?

The arc length of a circle can be calculated with the radius and central angle using the arc length formula, Length of an Arc = θ × r, where θ is in radian. Length of an Arc = θ × (π/180) × r, where θ is in degree.


1 Answers

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!

@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();
}

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

like image 163
andrew Avatar answered Oct 21 '22 19:10

andrew