tags:

views:

89

answers:

2

Hi all,

I have a few sets of information available to me, currently:

  • position on screen (Point)
  • orientation of point (double, say 15 degrees)
  • distance (length from point)

What I want to do is pick X (less than 6 I think) number of points in an angular spread facing the same orientation as the position with a distance of distance so that they are always on screen.

I can do this, but my implementation does not take into account the fact that some of the points end up off the screen, and all my attempts are quite poor and overly complex.

Does anyone have a good way of doing this?

EDIT: Added graphic to show what im after...

alt text

+1  A: 

A simple way of "projecting" a point (X1, Y1) along a trajectory/orientation for a distance to X2, Y2 you can use the following;

 X2 = X1 + (int)(Math.Sin(orientation) * distance);
 Y2 = Y1 + (int)(Math.Cos(orientation) * distance);

Where orientation is a radian double value. You may want to round the result since (int) is a brutal way to convert to int.

If you want to pick a point X/Y that is atleast distance d from point pX, pY then you know that the hypotenuse ( SquareRoot ( (X-pX)^2 + (Y-pY)^2 ) is less than d^2.

Is X/Y less than d from pX/pY?

bool isTooClose = ( ((X - pY)*(X - pY)) + ((Y - pY)*(Y - pY)) < (d*d));

If you know the screen size, then just check the boundaries.

bool isOnScreen = ( (pY > 0) && (pX > 0) && (pX < Screen.Width) && (pY < Screen.Height));

If you want to know that a circle is completely on screen, use the above isOnScreen and subtract/add the radius of the circle to the boundary. For example

bool isCircleOnScreen = ( (pY > r) && (pX > r) && (pX < (Screen.Width - r)) && (pY < (Screen.Height - r)));

To pick a point (X2, Y2) on a circle you can use the formula at the top.

Dead account
Thank you, but like I said, I can do this, but I cannot find a good way to generate a sequence of these points so that they are not off the screen. If the point was in the top left corner, I would expect the points to be in a spread of 90deg total... I hope that makes sense :) Thanks for the help!
Mark
What I'm really after here is a list of 6 points that are spread around a circles edge, you have provided the tools, which I did manage to get working as well, but I cannot find out how to get these points. For example, if the point was in the center of the screen, the needed points would be spread around a 180 degrees at a distance D, but if it was in the top right corner, the points would be spread around an angle closer to 90 degrees
Mark
I got it working, thanks to your help, so Ill give you the correct answer.
Mark
+1  A: 

This ended up being my implementation:

private static int[] DetermineTagPointsRange(Point location, double orientation, float distance)
        {
            const int screenWidth = 1024;
            const int screenHieght = 768;
            const int sampleCount = 10;
            const int totalAngleSpread = 360;
            const int angleInc = totalAngleSpread / sampleCount;

            var lowestAngle = -1;
            var highestAngle = -1;

            for (var i = 0; i < sampleCount; i++)
            {
                var thisAngle = angleInc*i;
                var endPointX = location.X + (int)(Math.Sin(ToRad(thisAngle)) * distance);
                var endPointY = location.Y - (int)(Math.Cos(ToRad(thisAngle)) * distance);
                bool isOnScreen = ((endPointY > 0) && (endPointX > 0) && (endPointX < screenWidth) && (endPointY < screenHieght));

                if (isOnScreen)
                {
                    if (thisAngle <= lowestAngle || lowestAngle == -1)
                        lowestAngle = thisAngle;

                    if (thisAngle >= highestAngle || highestAngle == -1)
                        highestAngle = thisAngle;
                }
            }

            return new int[] {lowestAngle, highestAngle};
        }

Thanks for the help

Mark