2014-07-22 135 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;' –