根据方形中心+角度,在正方形上获取X,Y坐标

时间:2014-07-22 12:45:03

标签: .net math graph geometry trigonometry

在winform应用程序中,我将根据配置绘制一些图形。

我正在寻找最简洁的方法来获得基于角度的X; Y坐标位于正方形上。该角度(以度为单位)以数学约定给出(右侧0°,顶部90°,......),并表示我们搜索这些坐标的方向。

我知道这不是很清楚,所以我创建了一些原理图,它会更清晰: enter image description here

我所知道的:广场的一侧是:2*R,R代表内圈的半径。

我想找到红色圆圈中的X; Y坐标。

现在我有一个算法可以根据角度解决问题:

A) 如果我们的角度在305°和45°之间,我们知道X值(= R),并计算Y:

Y = R / cos(α) * sin(α)

B) 如果我们有45°和135°之间的角度,我们知道Y值(= R),并计算X:

...

首先,我不确定它是否会在所有情况下都有效,并且它会使代码几乎相同4次。

你对如何制作这种清洁剂有所了解吗?

(我在c#.net中开发,所以如果你知道在libs中帮助我的东西,可以很好)

修改 也许我找到了一个干净的方式,你认为它会起作用还是更简单? 想法是转换笛卡儿中的极值。为此,我们必须计算幅度。

αTemp = α % Math.PI /2; //We put it in the first quarter, it will not change the amplitude.
amplitude = R /cos(αTemp);

我们只需转换polar into cartesian

X = cos(α) * amplitude;
Y = sin(α) * amplitude;

3 个答案:

答案 0 :(得分:0)

您可以尝试这种方法:

if (Cos(Alpha) <>  0) and (Abs(Tg(Alpha)) <= 1)  then 
                                             //on vertical edge
    Y = R * Tg(Alpha) * Sign(Sin(Alpha))    //see picture below
    X = R * Sign(Cos(Alpha))               //left or right  edge
else              
                                           //on horizontal edge
    X = R * Cot(Alpha) * Sign(Cos(Alpha))
    Y = R * Sign(Sin(Alpha))                //top or bottom

关于切线的维基图片:

enter image description here

答案 1 :(得分:0)

我会寻求一种区分四种情况的解决方案,即角度所在的象限(0-90度,90-180度,180-270度和270-360度)。对于每种情况,只有矩形的两边是有趣的。对于这些,计算交点并采取更接近中心的交点。

要以不同的方式表达,如果您手头有一些射线相交的代码,请考虑由中心和角度定义的光线以及由矩形边界定义的四条线。计算光线和四条线的交点参数,并取所有非负系数的最小系数;这将是定义所需交叉点的系数。

答案 2 :(得分:0)

如果你看一下第一象限中角度小于45度的最简单的情况,你可以看到用圆上的点形成的三角形是与正方形上的点形成的三角形相似的三角形。

enter image description here

因此y值是角度正切的r倍。这不是一个连续的功能,所以你可以把它分成8个单独的部分 - 每个半象限一个。在c#:

    public struct Point
    {
        public double X;
        public double Y;
    }


    public static Point calculatePointOnSquare(double r, double angleInDegrees)
    {
        Point p;
        p.X = 0.0;
        p.Y = 0.0;

        double angle = (angleInDegrees % 360) * Math.PI /180;

        double angleModPiOverTwo = angle % (Math.PI/4);

        if (angle >= 0 && angle < Math.PI / 4)
        {
            p.X = r;
            p.Y = r * Math.Tan(angle);
        }
        else if (angle >= Math.PI / 4 && angle < Math.PI / 2)
        {
            p.X = r * Math.Tan(Math.PI/2 - angle);
            p.Y = r;
        }
        else if (angle >= Math.PI / 2 && angle < 3*Math.PI/4)
        {
            p.X = -1 * r * Math.Tan(angle % (Math.PI/4));
            p.Y = r;
        }
        else if (angle >= 3*Math.PI/4 && angle < Math.PI)
        {
            p.X = -1 * r;
            p.Y = r * Math.Tan(Math.PI - angle);
        }
        else if (angle >= Math.PI && angle < 5*Math.PI/4)
        {
            p.X = -1 * r;
            p.Y = -1 * r * Math.Tan(angle % (Math.PI/4));
        }
        else if (angle >= 5*Math.PI/4 && angle < 3*Math.PI/2)
        {
            p.X = -1 * r * Math.Tan(3*Math.PI/2 - angle);
            p.Y = -1 * r;
        }
        else if (angle >= 3*Math.PI/2 && angle < 7*Math.PI/4)
        {
            p.X = r * Math.Tan(angle % (Math.PI/4));
            p.Y = -1 * r;
        }
        else
        {
            p.X = r;
            p.Y = -1 * r * Math.Tan(2 * Math.PI - angle);
        }

        return p;
    }