private VoronoiRegion GetVoronoiRegion(ref Vector3 p)
{
//The point we are comparing against the triangle is 0,0,0, so instead of storing an "A->P" vector,
//just use -A.
//Same for B->, C->P...
Vector3 ab, ac, ap;
Vector3.Subtract(ref triangle.vB, ref triangle.vA, out ab);
Vector3.Subtract(ref triangle.vC, ref triangle.vA, out ac);
Vector3.Subtract(ref p, ref triangle.vA, out ap);
//Check to see if it's outside A.
float APdotAB, APdotAC;
Vector3.Dot(ref ap, ref ab, out APdotAB);
Vector3.Dot(ref ap, ref ac, out APdotAC);
if (APdotAC <= 0f && APdotAB <= 0)
{
//It is A!
return VoronoiRegion.A;
}
//Check to see if it's outside B.
float BPdotAB, BPdotAC;
Vector3 bp;
Vector3.Subtract(ref p, ref triangle.vB, out bp);
Vector3.Dot(ref ab, ref bp, out BPdotAB);
Vector3.Dot(ref ac, ref bp, out BPdotAC);
if (BPdotAB >= 0f && BPdotAC <= BPdotAB)
{
//It is B!
return VoronoiRegion.B;
}
//Check to see if it's outside AB.
float vc = APdotAB * BPdotAC - BPdotAB * APdotAC;
if (vc <= 0 && APdotAB > 0 && BPdotAB < 0) //Note > and < instead of => <=; avoids possibly division by zero
{
return VoronoiRegion.AB;
}
//Check to see if it's outside C.
float CPdotAB, CPdotAC;
Vector3 cp;
Vector3.Subtract(ref p, ref triangle.vC, out cp);
Vector3.Dot(ref ab, ref cp, out CPdotAB);
Vector3.Dot(ref ac, ref cp, out CPdotAC);
if (CPdotAC >= 0f && CPdotAB <= CPdotAC)
{
//It is C!
return VoronoiRegion.C;
}
//Check if it's outside AC.
float vb = CPdotAB * APdotAC - APdotAB * CPdotAC;
if (vb <= 0f && APdotAC > 0f && CPdotAC < 0f) //Note > instead of >= and < instead of <=; prevents bad denominator
{
return VoronoiRegion.AC;
}
//Check if it's outside BC.
float va = BPdotAB * CPdotAC - CPdotAB * BPdotAC;
if (va <= 0f && (BPdotAC - BPdotAB) > 0f && (CPdotAB - CPdotAC) > 0f)//Note > instead of >= and < instead of <=; prevents bad denominator
{
return VoronoiRegion.BC;
}
//On the face of the triangle.
return VoronoiRegion.ABC;
}