开发者

Pick X points on a circle which are on screen in C#

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 f开发者_高级运维act 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...

Pick X points on a circle which are on screen in C#


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜