15
votes

I'm trying to figure out how I could be able to calculate coordinates on a circle. For simplicity I made some images.

http://i.stack.imgur.com/y1F2y.png

That's the start with information I have. Now I need to calculate the new coordinates when for example the circle would turn 90 degrees to the right. Just like the next image:

http://i.stack.imgur.com/ckopK.png

I need to calculate the coordinates of the new red dot. (I also need this with different degrees such as 20 degrees).

To do this my plan was to do the following:

  • Calculate the distance between the two points
  • Calculate the degree between the north (up) and the given point
  • Calculate the new location with the degree (from a step back) + the degrees it needs to turn (in the images 90 degrees).

My first step is:

distance = Math.sqrt((point1.x-point2.x)*(point1.x-point2.x) + (point1.y-point2.y)*(point1.y-point2.y))

The part to calculate the new degrees is:

double theta = Math.atan2(targetPt.y - centerPt.y, targetPt.x - centerPt.x);
theta += Math.PI/2.0;

And the last part to calculate the new location would be:

double x = mMiddleView.getX() + distance * Math.cos(Math.toRadians(theta));
double y = mMiddleView.getY() + distance * Math.sin(Math.toRadians(theta));

However when I do these calculations with for example 0 degrees it still returns another value than the original coordinates.

Any help would be appreciated!

Edit for Philipp Jahoda:

My values are:

distance +- 70, currentDegree = 0.
PointF point = new PointF((float)mMiddleView.getX(), (float)mMiddleView.getY());
PointF point2 = getPosition(point, (float) distance, currentDegree);

and my results are:

center: PointF(490.0, 728.0) radius: 78.0 angle: 0.0
new point: PointF(568.0, 728.0)

As you can see, the degree is 0 so the point is not supposed to turn. It should keep the 490, 728 coordinates but it does not keep those.

3
Why can't you work in polar coordinates the entire time? Convert to Cartesian just for the display stage. - Bathsheba
Otherwise, this link might help you: en.wikipedia.org/wiki/Rotation_matrix - Bathsheba
You are using x and y the same. Be careful that x is increasing rightward while y is increasing downward so your targetPt.y - centerPt.y part should be the opposite among other things - Eypros
Another issue is theta += Math.PI/2.0; that this part rotates towards the opposite direction of that in your picture. Use theta -= Math.PI/2.0; instead - Eypros

3 Answers

19
votes

Thats how:

private PointF getPosition(PointF center, float radius, float angle) {

    PointF p = new PointF((float) (center.x + radius * Math.cos(Math.toRadians(angle))),
    (float) (center.y + radius* Math.sin(Math.toRadians(angle))));

    return p;
}

This method calculates the position around the center of a circle (center of your view) depending on radius and angle. Angle in degrees.

The returned PointF will contain the x- and y-coordinate of the calculated position.

Be aware that 0 degrees is at the very east position of the circle, 270 degrees is in the very north position of the circle:

enter image description here

So if the center of your view is at x: 100, y: 100 and you calculate the position with an angle of 0 degrees and a radius of 50, the result will be x: 150, y: 100

If you use angle 90 degrees and radius 50, the result will be x: 100, y: 150

It is used here in my charting libary, and it works.

0
votes

This need some mathematics here. You need to know if two lines are perpendicular to each other, The multiplication of those two lines gradient should equals to -1.

Then

m1=(770-500)/(540-400)=27/14

same way

m2=(y-770)/(x-540)

(x,y) is the point you want to find.

Now

m1*m2=-1

Now we got one equation. You need another since there are two variable needs to find

You can get another by considering the radius of the circle.

r=sqrt((540-400)^2+(770-500)^2)

Same way

r=sqrl((x-540)^2+(y-770)^2)

Now you got two equation and only needs to solve. This will give you two set of coordinates. Since there can be -90 and 90 degrees.

0
votes

One elegant way to accomplish this is using complex numbers, available for example here.

In pseudo-code:

z = (x_old + I*y_old)*exp(I*angle);
x_new = real(z);
y_new = imag(z);

NOTE: the rotation angle needs to be in radians. NOTE2: this assumes a circle centred at (0,0). Just add a shift if the center is not there.