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);
            }
        }
示例#2
0
        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;
        }
示例#3
0
        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);
        }
示例#4
0
 /// <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;
 }
示例#5
0
 /// <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;
 }
示例#6
0
        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;
        }
示例#7
0
        // 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;
        }