Example #1
0
        private double[] Line_IntersectionsWithSegment(Double2 v1, Double2 v2)
        {
            var k = (v2 - v1).Cross(B - A);

            if (DoubleUtils.RoughlyZeroSquared(k))
            {
                return(new double[0]);
            }
            return(new[] { (v2 - v1).Cross(v1 - A) / k });
        }
Example #2
0
        // Generate a curve coordinate extrapolator
        private static Func <Double2, Double4> CoordExtrapolator(CurveVertex[] vertices)
        {
            // Check for the length
            int vl = vertices.Length;

            if (vl == 1)
            {
                var v = vertices[0].CurveCoords;
                return(x => v);
            }
            // Extrapolate along the line
            else if (vl == 2)
            {
                var va = vertices[0];
                var vb = vertices[1];
                var dx = vb.Position - va.Position;

                return(delegate(Double2 x)
                {
                    var t = (x - va.Position).Dot(dx) / dx.LengthSquared;
                    return va.CurveCoords + t * (vb.CurveCoords - va.CurveCoords);
                });
            }
            // Extrapolate along a triangle
            else
            {
                // Choose a nonzero-area triangle
                int i = 0, ik = 1, ik2 = 2;
                for (; i < vl; i++)
                {
                    ik  = (i + 1) % vl;
                    ik2 = (i + 2) % vl;

                    var winding = vertices[i].Position.Cross(vertices[ik].Position)
                                  + vertices[ik].Position.Cross(vertices[ik2].Position)
                                  + vertices[ik2].Position.Cross(vertices[i].Position);

                    if (!DoubleUtils.RoughlyZeroSquared(winding))
                    {
                        break;
                    }
                }

                // If there is no nonzero-area triangle, choose the most distant vertices and pick their extrapolator
                if (i == vl)
                {
                    var imin = 0;
                    var imax = 0;

                    for (i = 1; i < vl; i++)
                    {
                        if (vertices[imin].Position.X > vertices[i].Position.X)
                        {
                            imin = i;
                        }
                        if (vertices[imax].Position.X < vertices[i].Position.X)
                        {
                            imax = i;
                        }
                    }

                    return(CoordExtrapolator(new[] { vertices[imin], vertices[imax] }));
                }

                var a   = vertices[i].Position;
                var dv1 = vertices[ik].Position - a;
                var dv2 = vertices[ik2].Position - a;
                var k   = dv1.Cross(dv2);

                var ta = vertices[i].CurveCoords;
                var tb = vertices[ik].CurveCoords;
                var tc = vertices[ik2].CurveCoords;

                return(delegate(Double2 x)
                {
                    var u = (x - a).Cross(dv2) / k;
                    var v = -(x - a).Cross(dv1) / k;
                    return ta + u * (tb - ta) + v * (tc - ta);
                });
            }
        }