自从我参加任何类型的数学课以来已经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 int[] InOctants(Vector2 relativeCenter, Vector2 startPoint, Vector2 endPoint)
private static bool IsInOctant(int oct, Vector2 center, Vector2 startPoint, Vector2 endPoint)
我的代码(非常非数学)看起来像这样(Segment
只有2 Vectors2
):
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;
}
我现在正在使用C#,但几乎可以转换任何东西。
有人投票决定关闭这个,因为我不清楚我在问什么......要说清楚。我正在使用黑客来确定线段通过的八分圆,在某些情况下我只是忽略它并将该段添加到我的所有列表中。如果可能的话,我想收紧代码并正确使用(使用几何)。我也想避免使用atan2,因为它很慢。
答案 0 :(得分: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)
。
一般来说,将有四个交叉点,划分五个交叉的八分圆。您可以通过查看x
,y
,x + y
,x - y
的符号来确定交叉点属于哪个八分圆。
完整的讨论需要一些努力,但我相信你会管理。