Example #1
0
        public static int WhichSide(Triangle2d V, Vector2D P, Vector2D D)
        {
            // Vertices are projected to the form P+t*D.  Return value is +1 if all
            // t > 0, -1 if all t < 0, 0 otherwise, in which case the line splits the
            // triangle.

            int positive = 0, negative = 0, zero = 0;

            for (int i = 0; i < 3; ++i)
            {
                double t = D.Dot(V[i] - P);
                if (t > (double)0)
                {
                    ++positive;
                }
                else if (t < (double)0)
                {
                    ++negative;
                }
                else
                {
                    ++zero;
                }

                if (positive > 0 && negative > 0)
                {
                    return(0);
                }
            }
            return(zero == 0 ? (positive > 0 ? 1 : -1) : 0);
        }
Example #2
0
 public static void TriangleLineRelations(
     Vector2D origin, Vector2D direction,
     Triangle2d tri, ref Vector3D dist, ref Vector3i sign,
     ref int positive, ref int negative, ref int zero)
 {
     positive = 0;
     negative = 0;
     zero     = 0;
     for (int i = 0; i < 3; ++i)
     {
         Vector2D diff = tri[i] - origin;
         dist[i] = diff.DotPerp(direction);
         if (dist[i] > math.MathUtil.ZeroTolerance)
         {
             sign[i] = 1;
             ++positive;
         }
         else if (dist[i] < -math.MathUtil.ZeroTolerance)
         {
             sign[i] = -1;
             ++negative;
         }
         else
         {
             dist[i] = 0.0;
             sign[i] = 0;
             ++zero;
         }
     }
 }
        /// <summary>
        /// Gets triangle.
        /// </summary>
        /// <param name="index">The triangle index.</param>
        /// <param name="positionComponent">The component where we look for position, must be
        /// correct format.</param>
        /// <remarks>This is not performance wise getter.</remarks>
        public Triangle2d Get2d(string positionComponent, uint index)
        {
            Triangle2d t = new Triangle2d();

            Get(positionComponent, index, t);
            return(t);
        }
        //#foreach instanced to 'Double2'


        /// <summary>
        /// Gets triangle.
        /// </summary>
        /// <param name="index">The triangle triangle index.</param>
        /// <remarks>This is not performance wise getter.</remarks>
        /// <returns></returns>
        public Triangle2d Get2d(uint index)
        {
            Triangle2d t = new Triangle2d();

            Get(CommonComponents.Position, index, t);
            return(t);
        }
        /// <summary>
        /// An array getter, optimized by reusing mappings.
        /// </summary>
        /// <param name="triangleIndex">The  triangle index offset.</param>
        /// <param name="positionComponent">The position component.</param>
        /// <param name="storage">Where to store result.</param>
        public void Get(string positionComponent, uint triangleIndex, Triangle2d[] storage)
        {
            if (triangleIndex + storage.Length >= shapeCount)
            {
                throw new ArgumentException("Index out of range, not that many triangles.");
            }

            if (indexBuffer != null)
            {
                uint[]     indices = indexBuffer.Getui(triangleIndex * 3, (uint)storage.Length * 3);
                Vector2d[] data    = query.Get2d(positionComponent, indices);

                for (int i = 0; i < storage.Length; i++)
                {
                    storage[i] = new Triangle2d(data[i * 3], data[i * 3 + 1], data[i * 3 + 2]);
                }
            }
            else
            {
                Vector2d[] data = query.Get2d(positionComponent, triangleIndex * 3, (uint)storage.Length * 3);

                for (int i = 0; i < storage.Length; i++)
                {
                    storage[i] = new Triangle2d(data[i * 3], data[i * 3 + 1], data[i * 3 + 2]);
                }
            }
        }
Example #6
0
        public KAABBTree(IList <Triangle2d> mesh)
        {
            _boxes = new AxisAlignedBox2d[NumberOfAlignment];
            for (var i = 0; i < NumberOfAlignment; ++i)
            {
                var i1 = i;
                _boxes[i] = mesh.Select(tra => tra.Rotate(Alignment[i1])).GetBBox();
            }

            var alignmentToSplitBy = Random.Next(NumberOfAlignment);

            mesh = (_boxes[alignmentToSplitBy].Height > _boxes[alignmentToSplitBy].Width ?
                    mesh.OrderBy(tra => (Alignment[alignmentToSplitBy] * tra.V0).y)
                : mesh.OrderBy(tra => (Alignment[alignmentToSplitBy] * tra.V0).x)).ToList();
            if (mesh.Count != 1)
            {
                _isALeef = false;
                var midIndex = mesh.Count / 2;
                _left  = new KAABBTree(mesh.Take(midIndex).ToList());
                _right = new KAABBTree(mesh.Skip(midIndex).Take(mesh.Count - midIndex).ToList());
            }
            else
            {
                _isALeef = true;
                _mesh    = mesh.First();
            }
        }
        public void Contains_Triangle2d_V2d()
        {
            var t = new Triangle2d(new V2d(0, 0), new V2d(2, 0), new V2d(1, 2));

            Assert.IsTrue(t.Contains(new V2d(1, 1)));
            Assert.IsTrue(t.Contains(new V2d(2, 0)));
            Assert.IsTrue(!t.Contains(new V2d(0, 0.000001)));
        }
        public void Contains_Triangle2d_Triangle2d()
        {
            var t = new Triangle2d(new V2d(0, 0), new V2d(2, 0), new V2d(1, 2));

            Assert.IsTrue(t.Contains(new Triangle2d(new V2d(0, 0), new V2d(2, 0), new V2d(1, 2))));
            Assert.IsTrue(t.Contains(new Triangle2d(new V2d(0.2, 0.1), new V2d(1.5, 0.5), new V2d(1, 1.5))));
            Assert.IsTrue(!t.Contains(new Triangle2d(new V2d(0.2, 0.1), new V2d(1.5, 0.5), new V2d(1, 2.000001))));
            Assert.IsTrue(!t.Contains(new Triangle2d(new V2d(-1, -1), new V2d(3, -1), new V2d(1, 5))));
        }
        public void Contains_Triangle2d_Quad2d()
        {
            var t = new Triangle2d(new V2d(0, 0), new V2d(2, 0), new V2d(1, 2));

            Assert.IsTrue(t.Contains(new Quad2d(new V2d(0, 0), new V2d(2, 0), new V2d(1, 2), new V2d(1, 2))));
            Assert.IsTrue(t.Contains(new Quad2d(new V2d(0, 0), new V2d(2, 0), new V2d(1.5, 0.2), new V2d(0.5, 0.2))));
            Assert.IsTrue(!t.Contains(new Quad2d(new V2d(0, 0), new V2d(2, 0), new V2d(1.5, 0.2), new V2d(0.5, 1.1))));
            Assert.IsTrue(!t.Contains(new Quad2d(new V2d(-1, -1), new V2d(5, -1), new V2d(5, 5), new V2d(0, 5))));
        }
        public void Contains_Triangle2d_Circle2d()
        {
            var t = new Triangle2d(new V2d(0, 0), new V2d(2, 0), new V2d(1, 2));

            Assert.IsTrue(t.Contains(new Circle2d(new V2d(1, 1), 0.5)));
            Assert.IsTrue(t.Contains(new Circle2d(new V2d(1, 2), 0.0)));
            Assert.IsTrue(!t.Contains(new Circle2d(new V2d(1, 0.1), 0.100001)));
            Assert.IsTrue(!t.Contains(new Circle2d(new V2d(1, 2), 10)));
        }
        public void Contains_Triangle2d_Line2d()
        {
            var t = new Triangle2d(new V2d(0, 0), new V2d(2, 0), new V2d(1, 2));

            Assert.IsTrue(t.Contains(new Line2d(new V2d(0, 0), new V2d(2, 0))));
            Assert.IsTrue(t.Contains(new Line2d(new V2d(2, 0), new V2d(1, 2))));
            Assert.IsTrue(t.Contains(new Line2d(new V2d(1, 2), new V2d(0, 0))));
            Assert.IsTrue(t.Contains(new Line2d(new V2d(0.5, 0.1), new V2d(1.5, 0.2))));
            Assert.IsTrue(!t.Contains(new Line2d(new V2d(0.5, 0.1), new V2d(2, 2))));
            Assert.IsTrue(!t.Contains(new Line2d(new V2d(0.1, 0.2), new V2d(1.1, 10))));
        }
Example #12
0
        /// <summary>
        /// Fills a triangle at index.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="triangle">The triangle to be filled.</param>
        public void Get(uint index, [NotNull] Triangle2d triangle)
        {
            int idx = (int)index;

            if (IsIndexed)
            {
                triangle.A = vertices[(int)indices[idx * 3]];
                triangle.B = vertices[(int)indices[idx * 3 + 1]];
                triangle.C = vertices[(int)indices[idx * 3 + 2]];
            }
            else
            {
                triangle.A = vertices[3 * idx];
                triangle.B = vertices[3 * idx + 1];
                triangle.C = vertices[3 * idx + 2];
            }
        }
Example #13
0
 public AABBTree(IList <Triangle2d> mesh)
 {
     _box = mesh.GetBBox();
     mesh = (_box.Height > _box.Width ?
             mesh.OrderBy(tra => tra.V0.y)
         : mesh.OrderBy(tra => tra.V0.x)).ToList();
     if (mesh.Count != 1)
     {
         _isALeef = false;
         var midIndex = mesh.Count / 2;
         _left  = new AABBTree(mesh.Take(midIndex).ToList());
         _right = new AABBTree(mesh.Skip(midIndex).Take(mesh.Count - midIndex).ToList());
     }
     else
     {
         _isALeef = true;
         _mesh    = mesh.First();
     }
 }
        /// <summary>
        /// Gets triangle.
        /// </summary>
        /// <param name="index">The triangle triangle index.</param>
        /// <remarks>This accessor is not to be used in performance critical parts of applications.</remarks>
        /// <returns></returns>
        public void Get(string positionComponent, uint index, Triangle2d storage)
        {
            if (index >= shapeCount)
            {
                throw new ArgumentException("Index out of range, not that many triangles.");
            }

            if (indexBuffer != null)
            {
                uint[] indices = indexBuffer.Getui(index * 3, 3);

                storage.A = query.Get2d(positionComponent, indices[0]);
                storage.B = query.Get2d(positionComponent, indices[1]);
                storage.C = query.Get2d(positionComponent, indices[2]);
            }
            else
            {
                storage.A = query.Get2d(positionComponent, index * 3);
                storage.B = query.Get2d(positionComponent, index * 3 + 1);
                storage.C = query.Get2d(positionComponent, index * 3 + 2);
            }
        }
 /// <summary>
 /// Gets triangle.
 /// </summary>
 /// <param name="index">The triangle index.</param>
 /// <param name="positionComponent">The component where we look for position, must be
 /// Vector2f format.</param>
 /// <remarks>This is not performance wise getter.</remarks>
 public void Get(uint index, Triangle2d storage)
 {
     Get(CommonComponents.Position, index, storage);
 }
 public void CodeTriangle2d(ref Triangle2d v)
 {
     AddValue(v.ToString());
 }
Example #17
0
 public IntrSegment2Triangle2(Segment2d s, Triangle2d t)
 {
     segment = s; triangle = t;
 }
Example #18
0
 public void CodeTriangle2d(ref Triangle2d v)
 {
     CodeV2d(ref v.P0); CodeV2d(ref v.P1); CodeV2d(ref v.P2);
 }
Example #19
0
 public IntrTriangle2Triangle2(Triangle2d t0, Triangle2d t1)
 {
     triangle0 = t0;
     triangle1 = t1;
     Points    = null;
 }
 /// <summary>
 /// Generates a uniform distributed random sample on the given triangle using
 /// two random variables x1 and x2.
 /// </summary>
 public static V2d Triangle(Triangle2d t, double x1, double x2)
 {
     return(Triangle(t.P0, t.P1, t.P2, x1, x2));
 }
Example #21
0
 public IntrLine2Triangle2(Line2d l, Triangle2d t)
 {
     line = l; triangle = t;
 }
Example #22
0
        public static void GetInterval(Vector2D origin, Vector2D direction, Triangle2d tri,
                                       Vector3D dist, Vector3i sign, ref Vector2D param)
        {
            // Project triangle onto line.
            Vector3D proj = Vector3D.Zero;
            int      i;

            for (i = 0; i < 3; ++i)
            {
                Vector2D diff = tri[i] - origin;
                proj[i] = direction.Dot(diff);
            }

            // Compute transverse intersections of triangle edges with line.
            double numer, denom;
            int    i0, i1, i2;
            int    quantity = 0;

            for (i0 = 2, i1 = 0; i1 < 3; i0 = i1++)
            {
                if (sign[i0] * sign[i1] < 0)
                {
                    if (quantity >= 2)
                    {
                        throw new Exception("IntrLine2Triangle2.GetInterval: too many intersections!");
                    }
                    numer             = dist[i0] * proj[i1] - dist[i1] * proj[i0];
                    denom             = dist[i0] - dist[i1];
                    param[quantity++] = numer / denom;
                }
            }

            // Check for grazing contact.
            if (quantity < 2)
            {
                for (i0 = 1, i1 = 2, i2 = 0; i2 < 3; i0 = i1, i1 = i2++)
                {
                    if (sign[i2] == 0)
                    {
                        if (quantity >= 2)
                        {
                            throw new Exception("IntrLine2Triangle2.GetInterval: too many intersections!");
                        }
                        param[quantity++] = proj[i2];
                    }
                }
            }

            // Sort.
            if (quantity < 1)
            {
                throw new Exception("IntrLine2Triangle2.GetInterval: need at least one intersection");
            }
            if (quantity == 2)
            {
                if (param[0] > param[1])
                {
                    double save = param[0];
                    param[0] = param[1];
                    param[1] = save;
                }
            }
            else
            {
                param[1] = param[0];
            }
        }
Example #23
0
        bool IntersectsSegment(ref Plane3d plane, ref Triangle3d triangle, Vector3D end0, Vector3D end1)
        {
            // Compute the 2D representations of the triangle vertices and the
            // segment endpoints relative to the plane of the triangle.  Then
            // compute the intersection in the 2D space.

            // Project the triangle and segment onto the coordinate plane most
            // aligned with the plane normal.
            int    maxNormal = 0;
            double fmax      = Math.Abs(plane.Normal.x);
            double absMax    = Math.Abs(plane.Normal.y);

            if (absMax > fmax)
            {
                maxNormal = 1;
                fmax      = absMax;
            }
            absMax = Math.Abs(plane.Normal.z);
            if (absMax > fmax)
            {
                maxNormal = 2;
            }

            Triangle2d projTri = new Triangle2d();
            Vector2D   projEnd0 = Vector2D.Zero, projEnd1 = Vector2D.Zero;
            int        i;

            if (maxNormal == 0)
            {
                // Project onto yz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri[i] = triangle[i].yz;
                    projEnd0.x = end0.y;
                    projEnd0.y = end0.z;
                    projEnd1.x = end1.y;
                    projEnd1.y = end1.z;
                }
            }
            else if (maxNormal == 1)
            {
                // Project onto xz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri[i] = triangle[i].xz;
                    projEnd0.x = end0.x;
                    projEnd0.y = end0.z;
                    projEnd1.x = end1.x;
                    projEnd1.y = end1.z;
                }
            }
            else
            {
                // Project onto xy-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri[i] = triangle[i].xy;
                    projEnd0.x = end0.x;
                    projEnd0.y = end0.y;
                    projEnd1.x = end1.x;
                    projEnd1.y = end1.y;
                }
            }

            Segment2d             projSeg = new Segment2d(projEnd0, projEnd1);
            IntrSegment2Triangle2 calc    = new IntrSegment2Triangle2(projSeg, projTri);

            if (!calc.Find())
            {
                return(false);
            }

            Vector2dTuple2 intr = new Vector2dTuple2();

            if (calc.Type == IntersectionType.Segment)
            {
                Result   = IntersectionResult.Intersects;
                Type     = IntersectionType.Segment;
                Quantity = 2;
                intr.V0  = calc.Point0;
                intr.V1  = calc.Point1;
            }
            else
            {
                Debug.Assert(calc.Type == IntersectionType.Point);
                //"Intersection must be a point\n";
                Result   = IntersectionResult.Intersects;
                Type     = IntersectionType.Point;
                Quantity = 1;
                intr.V0  = calc.Point0;
            }

            // Unproject the segment of intersection.
            if (maxNormal == 0)
            {
                double invNX = ((double)1) / plane.Normal.x;
                for (i = 0; i < Quantity; ++i)
                {
                    double y = intr[i].x;
                    double z = intr[i].y;
                    double x = invNX * (plane.Constant - plane.Normal.y * y - plane.Normal.z * z);
                    Points[i] = new Vector3D(x, y, z);
                }
            }
            else if (maxNormal == 1)
            {
                double invNY = ((double)1) / plane.Normal.y;
                for (i = 0; i < Quantity; ++i)
                {
                    double x = intr[i].x;
                    double z = intr[i].y;
                    double y = invNY * (plane.Constant - plane.Normal.x * x - plane.Normal.z * z);
                    Points[i] = new Vector3D(x, y, z);
                }
            }
            else
            {
                double invNZ = ((double)1) / plane.Normal.z;
                for (i = 0; i < Quantity; ++i)
                {
                    double x = intr[i].x;
                    double y = intr[i].y;
                    double z = invNZ * (plane.Constant - plane.Normal.x * x - plane.Normal.y * y);
                    Points[i] = new Vector3D(x, y, z);
                }
            }

            return(true);
        }
Example #24
0
        /// <summary>
        /// Gets the centroid of the polyline.
        /// </summary>
        /// <param name="pl">The instance to which the method applies.</param>
        /// <returns>The centroid of the polyline (OCS coordinates).</returns>
        public static Point2d Centroid2d(this Polyline pl)
        {
            Point2d cen = new Point2d();
            Triangle2d tri = new Triangle2d();
            CircularArc2d arc = new CircularArc2d();
            double tmpArea;
            double area = 0.0;
            int last = pl.NumberOfVertices - 1;
            Point2d p0 = pl.GetPoint2dAt(0);
            double bulge = pl.GetBulgeAt(0);

            if (bulge != 0.0)
            {
                arc = pl.GetArcSegment2dAt(0);
                area = arc.AlgebricArea();
                cen = arc.Centroid() * area;
            }
            for (int i = 1; i < last; i++)
            {
                tri.Set(p0, pl.GetPoint2dAt(i), pl.GetPoint2dAt(i + 1));
                tmpArea = tri.AlgebricArea;
                cen += (tri.Centroid * tmpArea).GetAsVector();
                area += tmpArea;
                bulge = pl.GetBulgeAt(i);
                if (bulge != 0.0)
                {
                    arc = pl.GetArcSegment2dAt(i);
                    tmpArea = arc.AlgebricArea();
                    area += tmpArea;
                    cen += (arc.Centroid() * tmpArea).GetAsVector();
                }
            }
            bulge = pl.GetBulgeAt(last);
            if ((bulge != 0.0) && (pl.Closed == true))
            {
                arc = pl.GetArcSegment2dAt(last);
                tmpArea = arc.AlgebricArea();
                area += tmpArea;
                cen += (arc.Centroid() * tmpArea).GetAsVector();
            }
            return cen.DivideBy(area);
        }
Example #25
0
 /// <summary>
 /// Obtains a collection of triangles.
 /// </summary>
 /// <param name="index">The base index.</param>
 /// <param name="count">Number of triangles.</param>
 /// <returns>The triangle collection.</returns>
 public Triangle2d[] Get(uint index, uint count)
 {
     Triangle2d[] data = new Triangle2d[count];
     Get(index, data);
     return(data);
 }
Example #26
0
 public static Triangle2d Rotate(this Triangle2d tra, Matrix2d rotationMatrix)
 {
     return(new Triangle2d(rotationMatrix * tra[0],
                           rotationMatrix * tra[1],
                           rotationMatrix * tra[2]));
 }
Example #27
0
        bool GetCoplanarIntersection(ref Plane3d plane, ref Triangle3d tri0, ref Triangle3d tri1)
        {
            // Project triangles onto coordinate plane most aligned with plane
            // normal.
            int    maxNormal = 0;
            double fmax      = Math.Abs(plane.Normal.x);
            double absMax    = Math.Abs(plane.Normal.y);

            if (absMax > fmax)
            {
                maxNormal = 1;
                fmax      = absMax;
            }
            absMax = Math.Abs(plane.Normal.z);
            if (absMax > fmax)
            {
                maxNormal = 2;
            }

            Triangle2d projTri0 = new Triangle2d(), projTri1 = new Triangle2d();
            int        i;

            if (maxNormal == 0)
            {
                // Project onto yz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].yz;
                    projTri1[i] = tri1[i].yz;
                }
            }
            else if (maxNormal == 1)
            {
                // Project onto xz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].xz;
                    projTri1[i] = tri1[i].xz;
                }
            }
            else
            {
                // Project onto xy-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].xy;
                    projTri1[i] = tri1[i].xy;
                }
            }

            // 2D triangle intersection routines require counterclockwise ordering.
            Vector2D save;
            Vector2D edge0 = projTri0[1] - projTri0[0];
            Vector2D edge1 = projTri0[2] - projTri0[0];

            if (edge0.DotPerp(edge1) < (double)0)
            {
                // Triangle is clockwise, reorder it.
                save        = projTri0[1];
                projTri0[1] = projTri0[2];
                projTri0[2] = save;
            }

            edge0 = projTri1[1] - projTri1[0];
            edge1 = projTri1[2] - projTri1[0];
            if (edge0.DotPerp(edge1) < (double)0)
            {
                // Triangle is clockwise, reorder it.
                save        = projTri1[1];
                projTri1[1] = projTri1[2];
                projTri1[2] = save;
            }

            IntrTriangle2Triangle2 intr = new IntrTriangle2Triangle2(projTri0, projTri1);

            if (!intr.Find())
            {
                return(false);
            }

            PolygonPoints = new Vector3D[intr.Quantity];

            // Map 2D intersections back to the 3D triangle space.
            Quantity = intr.Quantity;
            if (maxNormal == 0)
            {
                double invNX = ((double)1) / plane.Normal.x;
                for (i = 0; i < Quantity; i++)
                {
                    double y = intr.Points[i].x;
                    double z = intr.Points[i].y;
                    double x = invNX * (plane.Constant - plane.Normal.y * y - plane.Normal.z * z);
                    PolygonPoints[i] = new Vector3D(x, y, z);
                }
            }
            else if (maxNormal == 1)
            {
                double invNY = ((double)1) / plane.Normal.y;
                for (i = 0; i < Quantity; i++)
                {
                    double x = intr.Points[i].x;
                    double z = intr.Points[i].y;
                    double y = invNY * (plane.Constant - plane.Normal.x * x - plane.Normal.z * z);
                    PolygonPoints[i] = new Vector3D(x, y, z);
                }
            }
            else
            {
                double invNZ = ((double)1) / plane.Normal.z;
                for (i = 0; i < Quantity; i++)
                {
                    double x = intr.Points[i].x;
                    double y = intr.Points[i].y;
                    double z = invNZ * (plane.Constant - plane.Normal.x * x - plane.Normal.y * y);
                    PolygonPoints[i] = new Vector3D(x, y, z);
                }
            }

            Result = IntersectionResult.Intersects;
            Type   = IntersectionType.Polygon;
            return(true);
        }
 /// <summary>
 /// An array getter, optimized by reusing mappings.
 /// </summary>
 /// <param name="triangleIndex">The triangle index offset.</param>
 /// <param name="positionComponent">The position component.</param>
 /// <param name="count">Number of triangles.</param>
 public Triangle2d[] Get2d(string positionComponent, uint triangleIndex, uint count)
 {
     Triangle2d[] data = new Triangle2d[count];
     Get(positionComponent, triangleIndex, data);
     return(data);
 }
 public void CodeTriangle2d(ref Triangle2d v)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Generates a uniform distributed random sample on the given triangle using
 /// two random series (seriesIndex,  seriesIndex + 1).
 /// </summary>
 public static V2d Triangle(Triangle2d t, IRandomSeries rnd, int seriesIndex)
 {
     return(Triangle(t.P0, t.P1, t.P2,
                     rnd.UniformDouble(seriesIndex),
                     rnd.UniformDouble(seriesIndex + 1)));
 }