2016-06-21 6 views
0

私は数学的なクラスを取ってから20年以上経っています。私はポイントが与え中心に対してに位置して八分円を決定するには、次のコードを使用しています:線分が通過する八角形を決定する

public static int GetOctant(Vector2 center, Vector2 target) 
{ 
    var adjusted = target - center; 
    int oct = 0; 

    if (adjusted.Y < 0) 
    { 
     adjusted *= -1; // rotate 180 
     oct += 4; 
    } 
    if (adjusted.X < 0) 
    { 
     adjusted = new Vector2(adjusted.Y, -adjusted.X); // rotate cw 90 
     oct += 2; 
    } 
    if (adjusted.X < adjusted.Y) 
     oct++; 

    return oct; 
} 

私は私の開始と終了のオクタントを与えることを、私のラインの両側のためにこれを行います。 もしそれらが1オクタント以上離れているなら、私はラインが通過する他のオクタントも知る必要があります。しかし、私はそれを行う方法を理解することはできません。

私はこのような方法のために期待しています:

private static List<Segment>[] PlaceInOctants(Vector2 center, IEnumerable<Segment> segments) 
{ 
    // We are creating lists of segments, 1 for each octant. 
    // Each list will contain any segment that touches that octant 
    var octants = new List<Segment>[8]; 
    for (int i = 0; i < octants.Length; i++) 
     octants[i] = new List<Segment>(); 

    foreach (Segment s in segments) 
    { 
     // Get the octant for the start/end points of the segments 
     var octantA = GetOctant(center, s.PointA); 
     var octantB = GetOctant(center, s.PointB); 
     if (octantA > octantB) 
     { 
      var tempOct = octantA; 
      octantA = octantB; 
      octantB = tempOct; 
     } 

     // Add the first segment to the first octants list 
     if (!octants[octantA].Contains(s)) 
      octants[octantA].Add(s); 

     // If octA & octB are different 
     if (octantA != octantB) 
     { 
      // We add the segment to the other list 
      if (!octants[octantB].Contains(s)) 
       octants[octantB].Add(s); 

      var diff = octantA - octantB; 
      if (diff < 0) 
       diff += 8; 
      if (diff > 4) 
       diff = 8 - diff; 
      // If A & B are 4 spaces apart (very rare) it's difficult to get 
      // the octants they pass through so we just add the segment 
      // to all the octants (it's going to pass through 5 out of 8 anyway) 
      // !!!! I'd like to do this right though !!!! 
      if (diff == 4) 
       for (int i = 0; i < octants.Length; i++) 
       { 
        if (octantA != i && octantB != i && !octants[i].Contains(s)) 
         octants[i].Add(s); 
       } 
      else 
      { 
       if (diff >= 2) 
       { 
        var oct = Math.Abs(diff) < 4 
         ? octantA < 7 ? octantA + 1 : 0 
         : octantA > 0 ? octantA - 1 : 7; 

        octants[oct].Add(s); 
       } 
       if (diff == 3) 
       { 
         var oct = Math.Abs(diff) > 4 
          ? octantB < 7 ? octantB + 1 : 0 
          : octantB > 0 ? octantB - 1 : 7; 
         octants[oct].Add(s); 
       } 
      } 
     } 
    } 
    return octants; 
} 
:(非常に非数理ある)

private static int[] InOctants(Vector2 relativeCenter, Vector2 startPoint, Vector2 endPoint) 

private static bool IsInOctant(int oct, Vector2 center, Vector2 startPoint, Vector2 endPoint) 

私のコードは、(Segmentはわずか2 Vectors2である)このようになります

私は現時点ではC#を使用していますが、何かから変換できます。

誰かが私が何を求めているのか分かりませんでしたので、これを閉じるように投票しました。私は、線分がどのオクタントを通過するかを決定するためにハックを使用しています。場合によっては無視して、すべてのリストにそのセグメントを追加します。可能であれば、そのコードを強化して(ジオメトリを使用して)正しく実行したいと思います。私はまた、atan2の使用が避けたいのですが、遅いです。

+2

ここに私が見つけたいくつかのpythonがあります:http://codereview.stackexchange.com/questions/95550/determining-which-octant-has-a-specific-point –

+0

あなたのラインは中心点を通りますか? – MBo

+0

Vector2は2dではありませんか?四分円を探していますか? – TaW

答えて

0

八分円は、x = 0,y = 0,x = y,x = -yの行で区切られている。対応するシステムを解くことによって、a.x + b.y + c = 0のような与えられた線との交差点を見つけることができます。

a.x + b.y + c = 0 
x = y 

例えば

x = y = - c/(a + b)を与えます。

一般に、交差する5つのオクタントを区切る4つの交差点があります。 xyx + yx - yの看板を見ることで交差点がどの八分円に属するかを特定することができます。

完全な議論には多少の努力が必要ですが、私はあなたが管理すると確信しています。

+0

お試しいただきありがとうございます。私はそこに書かれているものの約20%を理解しています。私はcの値をどこで得るのか分かりません。それでも私のコードでどのように動作するのかまだ分かりません。 –

+0

ラインセグメントでは、 'X = X0 + t(X1-X0)、Y = Y0 + t(Y1-Y0)'を使用する方が良いでしょう。 –

+0

どこから出ますか? –

関連する問題