我試圖爲Vector3s(或者說,VertexPositionNormalTextures)編寫一個Comparer類,它將按順時針順序排列它們的列表以修復我的背面剔除問題。我試圖在Web上調整一個非常常見的方法,它在兩個向量之間得到一個有符號的角度。但是,在運行時,我的列表會抱怨排序方法不一致,也就是說兩個項目在不同階段不一致比較,或者項目與自身進行比較,並且發現不相等。爲什麼我的Vector3s順時針排序不一致?
這裏的比較器類:
public class ClockwiseSorter : IComparer<VertexPositionNormalTexture>
{
private Vector3 center;
public ClockwiseSorter(Vector3 c)
{
center = c;
}
public int Compare(VertexPositionNormalTexture a, VertexPositionNormalTexture b)
{
Vector3 normal = Vector3.Cross(a.Position - center, b.Position - center);
normal.Normalize();
double theta = GetSignedAngleBetween2DVectors(a.Position - center, b.Position - center, Vector3.Cross(a.Position - center, normal));
if (theta > 0)
return -1;
else if (theta < 0)
return 1;
else
return 0;
}
/// Find the angle between two vectors. This will not only give the angle difference, but the direction.
/// For example, it may give you -1 radian, or 1 radian, depending on the direction. Angle given will be the
/// angle from the FromVector to the DestVector, in radians.
/// </summary>
/// <param name="FromVector">Vector to start at.</param>
/// <param name="DestVector">Destination vector.</param>
/// <param name="DestVectorsRight">Right vector of the destination vector</param>
/// <returns>Signed angle, in radians</returns>
/// <remarks>All three vectors must lie along the same plane.</remarks>
public static double GetSignedAngleBetween2DVectors(Vector3 FromVector, Vector3 DestVector, Vector3 DestVectorsRight)
{
FromVector.Normalize();
DestVector.Normalize();
DestVectorsRight.Normalize();
float forwardDot = Vector3.Dot(FromVector, DestVector);
float rightDot = Vector3.Dot(FromVector, DestVectorsRight);
// Keep dot in range to prevent rounding errors
forwardDot = MathHelper.Clamp(forwardDot, -1.0f, 1.0f);
double angleBetween = Math.Acos(forwardDot);
if (rightDot < 0.0f)
angleBetween *= -1.0f;
return angleBetween;
}
}
我通過平均所有向量的價值得到了中心向量:
private Vector3 AverageVectors(List<VertexPositionNormalTexture> vectors)
{
Vector3 sum = Vector3.Zero;
foreach (VertexPositionNormalTexture vector in vectors)
sum += vector.Position;
return (sum/vectors.Count);
}
難道我搞砸了某個地方,而不是想着這是否正確?還是我錯誤地計算了正常或中心?背面剔除已經只是一個頭痛對我來說,我是那種不顧一切地繼續......
我是否正確地假設你每次排序三個頂點?除此之外,對背面剔除問題沒有意義。 – TreDubZedd
我實際上正在排序4.這有點奇怪,是的。我正在排列四邊形而不是三角形水平,但如果這更容易,我可以輕鬆地過渡到三角形水平。 –