public double AngleToVec(GLVector vec) { // using first three points for creating plane vectors: if (Points.Count < 3) { return(0); } var plane = GLPlane.CreateFromPoints(Points[0], Points[1], Points[2]); var angleToNormal = plane.NormalVector.AngleToVec(vec); return(90 - angleToNormal); }
public static GLPlane CreateFromVectorsAndPoint(GLVector u, GLVector v, GLPoint P) { var plane = new GLPlane(); plane.Name = "plane"; plane.Position = P; var n = GLVector.CrossProduct(u, v); plane.NormalVector = n; plane.D = -n.X * P.X - n.Y * P.Y - n.Z * P.Z; return(plane); }
public double DistanceToPoint(GLPoint P) { // using first three points for creating plane vectors: if (Points.Count < 3) { return(-1); } var plane = GLPlane.CreateFromPoints(Points[0], Points[1], Points[2]); // computing line (made by observer view) - plane cross var viewLine = new GLLine(); viewLine.Position = P; viewLine.LineVector = plane.NormalVector; var cross = plane.CrossWithLine(viewLine); // geting polygon center to determine right half-plane var center = new GLPoint( (Points[0].X + Points[1].X + Points[2].X) / 3, (Points[0].Y + Points[1].Y + Points[2].Y) / 3, (Points[0].Z + Points[1].Z + Points[2].Z) / 3); // creating polygon-edge planes: //Logger.WriteToLog("Generating edge planes and lines"); var edgeLines = new List <GLLine>(); var pointInsideEdgePlanes = true; for (var i = 0; i < Points.Count; i++) { var A = Points[i]; var B = i + 1 <= Points.Count - 1 ? Points[i + 1] : Points[0]; var u = new GLVector(A, B); var edgePlane = GLPlane.CreateFromVectorsAndPoint(u, plane.NormalVector, A); // testing center half-plane position var centerInUpperHalfPlane = edgePlane.PointInUpperHalfPlane(center); var crossInUpperHalfPlane = edgePlane.PointInUpperHalfPlane(cross); edgeLines.Add(GLLine.CrateFromPoints(A, B)); if (centerInUpperHalfPlane != crossInUpperHalfPlane) { pointInsideEdgePlanes = false; break; } } //Logger.WriteToLog(" cross: " + cross.ToString()); if (pointInsideEdgePlanes) { // point inside edge planes //Logger.WriteToLog(" point inside edge planes"); return(cross.DistanceToPoint(P)); } else { //Logger.WriteToLog("detecting minimal distance to all edge lines"); var minDistance = double.MaxValue; foreach (var line in edgeLines) { if (line.LineVector.IsZero) { continue; } var intersectionT = line.IntersectionWithPerpendicularThroughPointParamTValue(P); //Logger.WriteToLog(" intersectionT param value: " + intersectionT.ToString()); if (intersectionT == double.MinValue) { return(-1); } if (intersectionT < 0) { // distance to A var distanceToA = P.DistanceToPoint(line.Position); if (distanceToA < minDistance) { minDistance = distanceToA; } } else if (intersectionT > 1) { // distance to B var B = line.PointByParam(1); var distanceToB = P.DistanceToPoint(B); if (distanceToB < minDistance) { minDistance = distanceToB; } } else { // distance to perpendicular line intersection var intersection = line.PointByParam(intersectionT); var distanceToLine = P.DistanceToPoint(intersection); if (distanceToLine < minDistance) { minDistance = distanceToLine; } } } if (minDistance == double.MaxValue) { return(-1); } return(minDistance); } }