public Quadrilateral(Point3 TopLeftIn, Point3 TopRightIn, Point3 BottomLeftIn, Point3 BottomRightIn) { this.TopLeft = TopLeftIn; this.TopRight = TopRightIn; this.BottomLeft = BottomLeftIn; this.BottomRight = BottomRightIn; Plane3 plane = new Plane3(this.TopLeft, this.TopRight, this.BottomLeft); //Vector3 ab = new Vector3(new Segment3(this.BottomLeft, this.TopLeft)); //Vector3 ac = new Vector3(new Segment3(this.BottomLeft, this.BottomRight)); //Vector3 normal = Vector3.Cross(ab, ac); //Vector3 ad = new Vector3(new Segment3(this.BottomLeft, this.TopRight)); //double dotp = Vector3.Dot(ad, normal); //PetrelLogger.InfoOutputWindow("The dot product of this cell's face is " + System.Convert.ToString(dotp)); if (Plane3Extensions.Contains(plane,this.BottomRight, 1E-7)) { LeftSegment = new Segment3(this.TopLeft, this.BottomLeft); RightSegment = new Segment3(this.TopRight, this.BottomRight); BottomSegment = new Segment3(this.BottomLeft, this.BottomRight); TopSegment = new Segment3(this.TopLeft, this.TopRight); CalculateCentroid(); } else { double x = (this.TopLeft.X + this.BottomLeft.X + this.TopRight.X + this.BottomRight.X) / 4.0; double y = (this.TopLeft.Y + this.BottomLeft.Y + this.TopRight.Y + this.BottomRight.Y) / 4.0; double z = (this.TopLeft.Z + this.BottomLeft.Z + this.TopRight.Z + this.BottomRight.Z) / 4.0; this.Centroid = new Point3(x,y,z); } }
public static bool PlaneIntersection(Plane3 a, Plane3 b, Plane3 c, out Vector3 point) { point = new Vector3(); float denom = Vector3.Dot(a.Normal, Vector3.Cross(b.Normal, c.Normal)); if (denom == 0.0f) { return false; } Vector3 n1 = a.Normal; Vector3 n2 = b.Normal; Vector3 n3 = b.Normal; float d1 = a.Distance; float d2 = b.Distance; float d3 = c.Distance; //point = n2.Cross(n3).Multiply(-d1).Subtract(n3.Cross(n1).Multiply(d2)).Subtract(n1.Cross(n2).Multiply(d3).Divide(denom)); //p = -d1 * ( n2.Cross ( n3 ) ) – d2 * ( n3.Cross ( n1 ) ) – d3 * ( n1.Cross ( n2 ) ) / denom; Vector3 pointA = Vector3.Multiply(Vector3.Cross(b.Normal, c.Normal), -a.Distance); Vector3 pointB = Vector3.Multiply(Vector3.Cross(c.Normal, a.Normal), b.Distance); Vector3 pointC = Vector3.Multiply(Vector3.Cross(a.Normal, b.Normal), c.Distance); point = Vector3.Subtract(pointA, pointB); point = Vector3.Subtract(point, pointC); point = Vector3.Divide(point, denom); return true; }
public static int BoxOnPlaneSide(float[] emins, float[] emaxs, Plane3 p) { Debug.Assert(emins.Length == 3 && emaxs.Length == 3, "vec3_t bug"); float dist1, dist2; int sides; // fast axial cases if (p.Type < 3) { if (p.Distance <= emins[p.Type]) { return(1); } if (p.Distance >= emaxs[p.Type]) { return(2); } return(3); } // general case switch (p.Signbits) { case 0: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 1: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 2: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 3: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 4: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 5: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 6: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; case 7: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; default: dist1 = dist2 = 0; Debug.Assert(false, "BoxOnPlaneSide bug"); break; } sides = 0; if (dist1 >= p.Distance) { sides = 1; } if (dist2 < p.Distance) { sides |= 2; } Debug.Assert(sides != 0, "BoxOnPlaneSide(): sides == 0 bug"); return(sides); }
/// <summary> /// Boxes the on plane side slow. /// </summary> /// <param name="emins">The emins.</param> /// <param name="emaxs">The emaxs.</param> /// <param name="p">The p.</param> /// <returns></returns> public static int BoxOnPlaneSideSlow(float[] emins, float[] emaxs, Plane3 p) { for (int i = 0; i < 3; i++) { if (p.normal[i] < 0) { corners[0][i] = emins[i]; corners[1][i] = emaxs[i]; } else { corners[1][i] = emins[i]; corners[0][i] = emaxs[i]; } } var dist1 = DotProduct(p.normal, corners[0]) - p.Distance; var dist2 = DotProduct(p.normal, corners[1]) - p.Distance; var sides = 0; if (dist1 >= 0) sides = 1; if (dist2 < 0) sides |= 2; return sides; }
/// <summary> /// Boxes the on plane side. /// </summary> /// <param name="emins">The emins.</param> /// <param name="emaxs">The emaxs.</param> /// <param name="p">The p.</param> /// <returns></returns> public static int BoxOnPlaneSide(float[] emins, float[] emaxs, Plane3 p) { Debug.Assert(emins.Length == 3 && emaxs.Length == 3, "vec3_t bug"); float dist1, dist2; int sides; // fast axial cases if (p.Type < 3) { if (p.Distance <= emins[p.Type]) return 1; if (p.Distance >= emaxs[p.Type]) return 2; return 3; } // general case switch (p.Signbits) { case 0: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 1: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 2: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 3: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 4: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 5: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 6: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; case 7: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; default: dist1 = dist2 = 0; Debug.Assert(false, "BoxOnPlaneSide bug"); break; } sides = 0; if (dist1 >= p.Distance) sides = 1; if (dist2 < p.Distance) sides |= 2; Debug.Assert(sides != 0, "BoxOnPlaneSide(): sides == 0 bug"); return sides; }
public SplitResult Slice(Plane3 plane, List<Entity> frontEntities, List<Entity> backEntities) { List<Brush> frontBrushes = new List<Brush>(); List<Brush> backBrushes = new List<Brush>(); List<Patch> frontPatches = new List<Patch>(); List<Patch> backPatches = new List<Patch>(); foreach (Brush b in Brushes) b.Slice(plane, frontEntities != null ? frontBrushes : null, backEntities != null ? backBrushes : null); int frontSideCt = frontBrushes.Count + frontPatches.Count; int backSideCt = backBrushes.Count + backPatches.Count; // Simple cases of entirely on front or back side first if (backSideCt == 0 && frontSideCt > 0) { if (frontEntities != null) frontEntities.Add(this); return SplitResult.Front; } else if (frontSideCt == 0 && backSideCt > 0) { if (backEntities != null) backEntities.Add(this); return SplitResult.Back; } else if (frontSideCt > 0 && backSideCt > 0) { // Divide this entity into 2 new entities containing the sperate geometries Entity frontEntity = new Entity(this); Entity backEntity = new Entity(this); foreach (Brush b in frontBrushes) { b.ComputeFaces(); frontEntity.Brushes.Add(b); } foreach (Brush b in backBrushes) { b.ComputeFaces(); backEntity.Brushes.Add(b); } if (frontEntities != null && frontEntity.Brushes.Count > 0) frontEntities.Add(frontEntity); if (backEntities != null && backEntity.Brushes.Count > 0) backEntities.Add(backEntity); return SplitResult.Split; } //if (Properties.ContainsKey("origin")) //{ // if (plane.GetDistance(GetOrigin()) > 0) // frontEntities.Add(this); // else // backEntities.Add(this); //} return SplitResult.None; }
// Slice the brush by a plane // If divided by the plane, results will be placed into the lists based on which side of th eplane they're on public SplitResult Slice(Plane3 plane, List<Brush> front, List<Brush> back) { List<Face> frontFaces = new List<Face>(); List<Face> backFaces = new List<Face>(); List<Winding> frontWinding = new List<Winding>(); List<Winding> backWinding = new List<Winding>(); foreach (Face f in Faces) { frontFaces.Clear(); backFaces.Clear(); Winding winding = new Winding(f.GetPlane()); winding.Clip(plane, frontWinding, backWinding); for (int i = 0; i < frontWinding.Count; ++i) { if (frontWinding[i].Count == 0) { frontWinding.RemoveAt(i); --i; } } for (int i = 0; i < backWinding.Count; ++i) { if (backWinding[i].Count == 0) { backWinding.RemoveAt(i); --i; } } // Brush needs to be split if (frontWinding.Count > 0 && backWinding.Count > 0) { Brush frontBrush = new Brush(); Brush backBrush = new Brush(); if (front != null) { foreach (Winding w in frontWinding) if (w.Count > 0) frontBrush.Faces.Add(new Face(f, w)); if (frontBrush.Faces.Count > 0) front.Add(frontBrush); } if (back != null) { foreach (Winding w in backWinding) { if (w.Count > 0) backBrush.Faces.Add(new Face(f, w)); } if (backBrush.Faces.Count > 0) back.Add(backBrush); } return SplitResult.Split; } // Brush is whole else if (frontWinding.Count > 0) { if (front != null) front.Add(this); return SplitResult.Front; } else if (backWinding.Count > 0) { if (back != null) back.Add(this); return SplitResult.Back; } else throw new Exception("Unexpected failure with brush neither on nor on a side of a plane"); } return SplitResult.None; }
public static int BoxOnPlaneSide(float[] emins, float[] emaxs, Plane3 p) { #if !CODE_ANALYSIS && CLR4 Contract.Assert(emins.Length == 3 && emaxs.Length == 3, "vec3_t bug"); #endif float dist1, dist2; int sides; // fast axial cases if (p.type < 3) { if (p.dist <= emins[p.type]) return 1; if (p.dist >= emaxs[p.type]) return 2; return 3; } // general case switch (p.signbits) { case 0: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 1: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; break; case 2: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 3: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; break; case 4: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 5: dist1 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emaxs[2]; break; case 6: dist1 = p.normal[0] * emaxs[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emins[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; case 7: dist1 = p.normal[0] * emins[0] + p.normal[1] * emins[1] + p.normal[2] * emins[2]; dist2 = p.normal[0] * emaxs[0] + p.normal[1] * emaxs[1] + p.normal[2] * emaxs[2]; break; default: dist1 = dist2 = 0; #if !CODE_ANALYSIS && CLR4 Contract.Assert(false, "BoxOnPlaneSide bug"); #endif break; } sides = 0; if (dist1 >= p.dist) sides = 1; if (dist2 < p.dist) sides |= 2; #if !CODE_ANALYSIS && CLR4 Contract.Assert(sides != 0, "BoxOnPlaneSide(): sides == 0 bug"); #endif return sides; }