private Vector3D FindCornerNormal(Point3D p, double eps)
{
var sum = new Vector3D();
int count = 0;
var addedNormals = new HashSet<Vector3D>();
for (int i = 0; i < this.triangleIndices.Count; i += 3)
{
int i0 = i;
int i1 = i + 1;
int i2 = i + 2;
var p0 = this.positions[this.triangleIndices[i0]];
var p1 = this.positions[this.triangleIndices[i1]];
var p2 = this.positions[this.triangleIndices[i2]];
// check if any of the vertices are on the corner
double d0 = (p - p0).LengthSquared;
double d1 = (p - p1).LengthSquared;
double d2 = (p - p2).LengthSquared;
double mind = Math.Min(d0, Math.Min(d1, d2));
if (mind > eps)
{
continue;
}
// calculate the triangle normal and check if this face is already added
var normal = Vector3D.CrossProduct(p1 - p0, p2 - p0);
normal.Normalize();
// todo: need to use the epsilon value to compare the normals?
if (addedNormals.Contains(normal))
{
continue;
}
// todo: this does not work yet
// double dp = 1;
// foreach (var n in addedNormals)
// {
// dp = Math.Abs(Vector3D.DotProduct(n, normal) - 1);
// if (dp < eps)
// continue;
// }
// if (dp < eps)
// {
// continue;
// }
count++;
sum += normal;
addedNormals.Add(normal);
}
if (count == 0)
{
return new Vector3D();
}
return sum * (1.0 / count);
}