views:

4975

answers:

5

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.

A: 

maybe the downcast from double to integer takes place.

modosansreves
Since the code includes the a cast "(int)" on the results of Math.Round which (oddly) returns a double, then I'd say that it's indeed a certainty that a cast from double to integer takes place. I wouldn't refer to it as a downcast, though, since there's no inheritance hierarchy between these types.
P Daddy
+3  A: 

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);
John Rasch
+2  A: 

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

MartinStettner
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.
x4000
+1  A: 

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.

JonBWalsh
You're exactly right, the angle input was actually off.
x4000
A: 

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?

Andrea Ambu