2014-07-22 134 views
1

在一个winform应用程序中,我必须根据配置绘制一些图形。基于方形中心+角度获取正方形上的X,Y坐标

我正在寻找最干净的方法来获取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次几乎相同的代码。

你有关于如何使这个更清洁的想法?

(我developp在C#.NET,所以如果你知道的东西,可以帮助我在库,可能是好的)

编辑 也许我找到了一个简洁的方式,你认为它会工作或有简单吗? 这个想法是转换笛卡儿的极坐标值。为了做到这一点,我们必须计算幅度。

α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; 

回答

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

0

我会寻找一种解决方案来区分四种情况,即角度所在的象限(0-90度,90-180度,180-270度和270-360度)。对于每种情况,只有矩形的两边感兴趣。对于这些,计算交点并采取更接近中心的交点。为了以不同的方式表述,如果手边有一些射线相交的代码,考虑由中心定义的射线以及由矩形边所定义的角度和四条线。计算射线和四条线的相交参数,取所有非负系数的最小系数;这将是定义所需交点的系数。

+0

是的,但这会带来4次相同类型的代码。我已经有了一个有效的例子,这不是很好 – J4N

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; 
    } 
+0

太脏了,对不起:/,我的4行代码现在更容易/更清洁 – J4N

+0

为什么你在这里使用360的mod? 'double angle =(angleInDegrees%360)* Math.PI/180;'。我认为它应该是'double angle = angleInDegrees * Math.PI/180;' –