Calculating point on a circle's circumference from angle in C#?
Asked Answered
N

6

42

I imagine that this is a simple question, but I'm getting some strange results with my current code and I don't have the math background to fully understand why. My goal is simple, as stated in the title: I just want to find the point at some distance and angle from a center point.

My current code:

Point centerPoint = new Point ( 0, 0 );
Point result      = new Point ( 0, 0 );
double angle      = 0.5; //between 0 and 2 * PI, angle is in radians
int distance      = 1000;

result.Y = centerPoint.Y + (int)Math.Round( distance * Math.Sin( angle ) );
result.X = centerPoint.X + (int)Math.Round( distance * Math.Cos( angle ) );

In general, this seems to work fairly reasonably, but I get problems at various spots, most notably when the angle corresponds to points in the negative x and y axis. Clearly I'm doing something wrong -- thoughts on what that is?

UPDATE: This was my mistake, this code works fine -- the few outliers that were not working were actually due to a bug in how the angle for 1.5PI was being calculated. I thought I had checked that well enough, but evidently had not. Thanks to everyone for their time, hopefully the working code above will prove helpful to someone else.

Nonsmoker answered 23/3, 2009 at 16:57 Comment(6)
What do you mean "i get problems at various spots"?Coworker
is centerPoint deliberately unused? Shouldn't centerPoint.X and .Y be added to result?Photomultiplier
can you provide an example of a problem?Flak
I don't expect you'll get more than shots in the dark until you describe what exactly is wrong with your results.Continental
Please do not refer to your distance as X and angle as Y. That is counter intuitive. Distance is your radius and angle is your... angle.Verbal
Ah, this is a good point about the centerpoint -- it is unused in this case. The specific point I'm working with at present is with a centerpoint of 0,0, so it's irrelevant in that case, but in other cases it would certainly make a difference.Nonsmoker
I
35

You forgot to add the center point:

result.Y = (int)Math.Round( centerPoint.Y + distance * Math.Sin( angle ) );
result.X = (int)Math.Round( centerPoint.X + distance * Math.Cos( angle ) );

The rest should be ok... (what strange results were you getting? Can you give an exact input?)

Iatry answered 23/3, 2009 at 17:19 Comment(1)
Ah, this is a good point about the centerpoint -- it is unused in this case. The specific point I'm working with at present is with a centerpoint of 0,0, so it's irrelevant in that case, but in other cases it would certainly make a difference. I've updated the example to properly include it.Nonsmoker
P
6

Firstly, since you're in radians it's probably beneficial to define your angle as such:

double angle = (Math.PI / 3); // 60 degrees...

The functions themselves are working fine. The rounding will only affect your answer if your distance is sufficiently small enough. Other than that, the answers should come out just fine.

If it's the rounding you're worried about, remember that by default, .NET does banker's rounding, and you may want:

result.X = (int)Math.Round(centerPoint.X + distance * Math.Cos(angle), MidpointRounding.AwayFromZero);
result.Y = (int)Math.Round(centerPoint.Y + distance * Math.Sin(angle), MidpointRounding.AwayFromZero);

instead.

Additionally, in the question you want distance X and angle Y... I assume you're not relating that to the point (X,Y), because that's completely different.

The distance formula is:

double distance = Math.Sqrt((centerPoint.X + result.X)^2 + (centerPoint.Y + result.Y)^2);
Parthenia answered 23/3, 2009 at 17:17 Comment(1)
John, Thanks for the fish. I was blissfully unaware that C# was rounding double calculations at all, let alone awfully (IMHO).Income
E
3

A Swift3 version

func pointOnCircle(radius: Double, angleInDegrees: Double, origin: CGPoint) -> CGPoint {
    let x = abs(Double(origin.x) + radius * cos(angleInDegrees * (.pi / 180)))
    let y = abs(Double(origin.y) - radius * sin(angleInDegrees * (.pi / 180)))

    return CGPoint(x: x, y: y)
}
Epanodos answered 8/8, 2017 at 19:43 Comment(0)
U
1

Without more information on the exact errors it's hard to tell what's wrong. The equations look right and should work. Are you sure the angles you are passing in are correct for angles > 90 degrees? The only other thing I could think of would be that you're multiplying distance (an int) by the result of Math.sin (double) but that shouldn't really be an issue.

Underpart answered 23/3, 2009 at 18:12 Comment(0)
T
1
-(NSMutableArray *)GetPointsForCircle
    {
       NSMutableArray *Points = [[NSMutableArray alloc] init];
       CGPoint CenterPoint = CGPointMake(160, 230);
       CGPoint Point;
       for (float Angel = 0; Angel <= 360; Angel+= 60)
         {
           Point.x = CenterPoint.x + 100 * cos(Angel);
           Point.y = CenterPoint.y + 100 * sin(Angel);
           [Points addObject:[NSValue valueWithCGPoint:Point]];
         }
       return Points;
    }

    - (CGPoint)pointOnCircle:(int)thisPoint withTotalPointCount:(int)totalPoints
     {
        CGPoint centerPoint = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
        float radius = 100.0;
        float angle = ( 2 * M_PI / (float)totalPoints ) * (float)thisPoint;
        CGPoint newPoint;
        newPoint.x = (centerPoint.x) + (radius * cosf(angle));
        newPoint.y = (centerPoint.y) + (radius * sinf(angle));
        return newPoint;   
    }
Tungstic answered 20/9, 2012 at 5:58 Comment(1)
Return 6 Points for a circle of radius 100. The parametric equation for a circle is x = cx + r * cos(a) y = cy + r * sin(a) Where r is the radius, cx,cy the origin, and a the angle from 0..2PI radians or 0..360 degrees.Tungstic
A
-1

I don't know c#, anyway if you are trying to draw the points somewhere you have to consider the fact that the Y axis crease from the top to the bottom of the screen, so your sin element should have be -sin(...) and not +sin(...)

so

result.Y = centerPoint.Y + (int)Math.Round( distance * Math.Sin( angle ) );

should become:

result.Y = centerPoint.Y - (int)Math.Round( distance * Math.Sin( angle ) );

If you are not trying to draw them I could not imagine what the problem is, can you give some example?

Angelinaangeline answered 23/3, 2009 at 18:18 Comment(2)
result.Y should use cos not sin check this link webdeveloper.com/forum/showthread.php?t=190439Ealing
@Ealing your link is deadMartellato

© 2022 - 2024 — McMap. All rights reserved.