Esempio n. 1
0
        public double DistanceSquared(Vector2D p, out int iNearSeg, out double fNearSegT)
        {
            iNearSeg  = -1;
            fNearSegT = double.MaxValue;
            double dist = double.MaxValue;
            int    N    = vertices.Count;

            for (int vi = 0; vi < N; ++vi)
            {
                Segment2d seg = new Segment2d(vertices[vi], vertices[(vi + 1) % N]);
                double    t   = (p - seg.Center).Dot(seg.Direction);
                double    d   = double.MaxValue;
                if (t >= seg.Extent)
                {
                    d = seg.P1.DistanceSquared(p);
                }
                else if (t <= -seg.Extent)
                {
                    d = seg.P0.DistanceSquared(p);
                }
                else
                {
                    d = (seg.PointAt(t) - p).LengthSquared;
                }
                if (d < dist)
                {
                    dist      = d;
                    iNearSeg  = vi;
                    fNearSegT = t;
                }
            }
            return(dist);
        }
Esempio n. 2
0
        public static Segment2d Project(this Segment2d _host, Segment2d _seg)
        {
            //project each end point
            double t0 = _host.Project(_seg.P0);
            double t1 = _host.Project(_seg.P1);

            t0 = MathUtil.Clamp(t0, -1.0 * _host.Extent, _host.Extent);
            t1 = MathUtil.Clamp(t1, -1.0 * _host.Extent, _host.Extent);
            if (t0.IsAlmostEqualByDifference(t1))
            {
                return(new Segment2d(Vector2d.Zero, Vector2d.Zero));
            }
            var p0 = _host.PointAt(t0);
            var p1 = _host.PointAt(t1);

            return(new Segment2d(p0, p1));
        }
Esempio n. 3
0
        // yikes not robust at all!!
        protected List <Segment2d> compute_polygon_ray_spans(GeneralPolygon2d poly, Segment2d ray, Vector2d axis_origin, Vector2d axis, double axisT, SegmentSet2d segments)
        {
            List <double> hits = new List <double>();               // todo reusable buffer

            segments.FindAllIntersections(ray, hits, null, null, false);
            hits.Sort();

            bool clean = true;

            for (int i = 0; i < hits.Count - 1 && clean; ++i)
            {
                if (hits[i + 1] - hits[i] < MathUtil.Epsilonf)
                {
                    clean = false;
                }
            }
            if (!clean)
            {
                hits = extract_valid_segments(poly, ray, hits);
            }

            if (hits.Count % 2 != 0)
            {
                throw new Exception("DenseLineFill.ComputeAllSpans: have not handled hard cases...");
            }

            List <Segment2d> spans = new List <Segment2d>();

            for (int i = 0; i < hits.Count / 2; ++i)
            {
                Vector2d p0 = ray.PointAt(hits[2 * i]);
                Vector2d p1 = ray.PointAt(hits[2 * i + 1]);
                spans.Add(new Segment2d(p0, p1));
            }

            return(spans);
        }
Esempio n. 4
0
        /// <summary>
        /// hits is a sorted list of t-values along ray. This function
        /// tries to pull out the valid pairs, ie where the segment between the
        /// pair is inside poly.
        ///
        /// numerical problems:
        ///    - no guarantee that all intersection t's are in hits list
        ///       (although we are being conservative in SegmentSet2d, testing extent+eps)
        ///    - poly.Contains() could return false for points very near to border
        ///       (in unfortunate case this means we discard valid segments. in
        ///        pathological case it means we produce invalid ones)
        /// </summary>
        List <double> extract_valid_segments(GeneralPolygon2d poly, Segment2d ray, List <double> hits)
        {
            double eps = MathUtil.Epsilonf;

            List <double> result = new List <double>();
            int           i      = 0;
            int           j      = i + 1;

            while (j < hits.Count)
            {
                // find next non-dupe
                while (j < hits.Count && hits[j] - hits[i] < eps)
                {
                    j++;
                }
                if (j == hits.Count)
                {
                    continue;
                }

                // ok check if midpoint is inside or outside
                double   mid_t = (hits[i] + hits[j]) * 0.5;
                Vector2d mid   = ray.PointAt(mid_t);

                // not robust...eek
                bool isInside = poly.Contains(mid);
                if (isInside)
                {
                    // ok we add this segment, and then we start looking at next point (?)
                    result.Add(hits[i]);
                    result.Add(hits[j]);
                    i = j + 1;
                    j = i + 1;
                }
                else
                {
                    // ok we were not inside, so start search at j
                    i = j;
                    j++;
                }
            }

            return(result);
        }
Esempio n. 5
0
        public Vector2D PointAt(int iSegment, double fSegT)
        {
            Segment2d seg = new Segment2d(vertices[iSegment], vertices[(iSegment + 1) % vertices.Count]);

            return(seg.PointAt(fSegT));
        }