示例#1
0
        protected static bool Parallel([NotNull] Pnt p0,
                                       [NotNull] Pnt l0,
                                       [NotNull] Pnt p1,
                                       [NotNull] Pnt l1,
                                       double r2,
                                       out double tMin, out double tMax,
                                       ref NearSegment hullStartNear,
                                       ref NearSegment hullEndNear)
        {
            if (SegmentUtils.CutLineCircle(p0, l0, p1, r2, out tMin, out tMax) == false)
            {
                return(false);
            }

            hullStartNear = Near(tMin, tMax);

            double cMin, cMax;

            if (SegmentUtils.CutLineCircle(p0, l0, p1 + l1, r2, out cMin, out cMax))
            {
                hullEndNear = Near(cMin, cMax);

                tMin = Math.Min(tMin, cMin);
                tMax = Math.Max(tMax, cMax);
            }

            return(true);
        }
示例#2
0
        private static bool CutArcLine(Pnt p, HullLineArc line, ref double tMin, ref double tMax)
        {
            bool   intersects = false;
            double r = line.Radius;
            double tCircleMin, tCircleMax;

            if (SegmentUtils.CutLineCircle(line.Lin.Ps, line.Lin.L, p, r * r,
                                           out tCircleMin, out tCircleMax))
            {
                intersects |= IsPointInArcDirection(p, line, tCircleMin, ref tMin, ref tMax);
                intersects |= IsPointInArcDirection(p, line, tCircleMax, ref tMin, ref tMax);
            }

            return(intersects);
        }
示例#3
0
        private bool CutLineEndpoint(double angle, HullLineArc line, ref double tMin,
                                     ref double tMax)
        {
            var    intersects = false;
            double r = line.Radius;
            Pnt    p = _center + new Pnt2D(_radius * Math.Cos(angle), _radius * Math.Sin(angle));
            double tCircleMin, tCircleMax;

            if (SegmentUtils.CutLineCircle(line.Lin.Ps, line.Lin.L, p, r * r,
                                           out tCircleMin, out tCircleMax))
            {
                intersects |= ValidateIntersects(p, line, tCircleMin, ref tMin, ref tMax);
                intersects |= ValidateIntersects(p, line, tCircleMax, ref tMin, ref tMax);
            }

            return(intersects);
        }
示例#4
0
        private void CutCircle(Pnt segStart, Pnt segmentLine, double offset, ref double tMin,
                               ref double tMax)
        {
            Pnt    near         = _center - segStart;
            double centerOffset = SegmentUtils.GetOffset(near, segmentLine);

            if (Math.Abs(centerOffset) < offset)
            {
                double centerAlong   = SegmentUtils.GetAlongFraction(near, segmentLine);
                double segmentLength = Math.Sqrt(segmentLine.OrigDist2());

                tMin = Math.Min(tMin, centerAlong - _radius / segmentLength);
                tMax = Math.Max(tMax, centerAlong + _radius / segmentLength);
            }
            else if (_radius + offset > Math.Abs(centerOffset))
            {
                Pnt offsetCenter;
                if (offset <= 0)
                {
                    offsetCenter = _center;
                }
                else
                {
                    double centerAlong = SegmentUtils.GetAlongFraction(near, segmentLine);
                    Pnt    along       = segStart + centerAlong * segmentLine;
                    double f           = (Math.Abs(centerOffset) - offset) / Math.Abs(centerOffset);
                    offsetCenter = along + f * (_center - along);
                }

                double tCircleMin, tCircleMax;
                if (SegmentUtils.CutLineCircle(segStart, segmentLine, offsetCenter,
                                               _radius * _radius,
                                               out tCircleMin, out tCircleMax))
                {
                    tMin = Math.Min(tMin, tCircleMin);
                    tMax = Math.Max(tMax, tCircleMax);
                }
            }
        }
示例#5
0
        private bool CutLineThis(Pnt p0, Pnt l0, ref double tMin, ref double tMax,
                                 SignedHullLineArc arc = null)
        {
            double r = _radius + (arc?.Radius ?? 0);
            double tCircleMin;
            double tCircleMax;

            if (!SegmentUtils.CutLineCircle(
                    p0, l0, _center, r * r,
                    out tCircleMin, out tCircleMax))
            {
                return(false);
            }

            var cuts = false;

            double f = r > 0 ? 1 : -1;

            Pnt dirMin = p0 + tCircleMin * l0 - _center;

            if (ValidateAngles(f * dirMin, arc))
            {
                cuts = true;
                tMin = Math.Min(tMin, tCircleMin);
                tMax = Math.Max(tMax, tCircleMin);
            }

            Pnt dirMax = p0 + tCircleMax * l0 - _center;

            if (ValidateAngles(f * dirMax, arc))
            {
                cuts = true;
                tMin = Math.Min(tMin, tCircleMax);
                tMax = Math.Max(tMax, tCircleMax);
            }

            return(cuts);
        }
示例#6
0
        private void CutArc(Pnt segStart, Pnt segmentLine, double offset, ref double tMin,
                            ref double tMax)
        {
            Pnt    near         = _center - segStart;
            double centerOffset = SegmentUtils.GetOffset(near, segmentLine);

            if (Math.Abs(centerOffset) < offset)
            {
                var    canReturn     = false;
                double lineAngle     = Math.Atan2(segmentLine.Y, segmentLine.X);
                double centerAlong   = SegmentUtils.GetAlongFraction(near, segmentLine);
                double segmentLength = Math.Sqrt(segmentLine.OrigDist2());

                if (IsInArcAngle(lineAngle))
                {
                    canReturn = true;
                    tMax      = Math.Max(tMax, centerAlong + _radius / segmentLength);
                }

                double reverseLineAngle = lineAngle - Math.PI;
                if (IsInArcAngle(reverseLineAngle))
                {
                    tMin = Math.Min(tMin, centerAlong - _radius / segmentLength);
                    if (canReturn)
                    {
                        return;
                    }
                }
            }

            Pnt start = _center +
                        _radius * new Pnt2D(Math.Cos(StartDirection), Math.Sin(StartDirection))
                        - segStart;
            double startOffset = SegmentUtils.GetOffset(start, segmentLine);

            if (Math.Abs(startOffset) < offset)
            {
                double startAlong = SegmentUtils.GetAlongFraction(start, segmentLine);
                tMin = Math.Min(tMin, startAlong);
                tMax = Math.Max(tMax, startAlong);
            }

            double endDirection = StartDirection + (Angle ?? 0);
            Pnt    end          = _center +
                                  _radius * new Pnt2D(Math.Cos(endDirection), Math.Sin(endDirection))
                                  - segStart;
            double endOffset = SegmentUtils.GetOffset(end, segmentLine);

            if (Math.Abs(endOffset) < offset)
            {
                double endAlong = SegmentUtils.GetAlongFraction(end, segmentLine);
                tMin = Math.Min(tMin, endAlong);
                tMax = Math.Max(tMax, endAlong);
            }

            if (_radius + offset > Math.Abs(centerOffset))
            {
                var segmentStarts = new List <Pnt>();
                {
                    double segmentLength = Math.Sqrt(segmentLine.OrigDist2());
                    Pnt    off           = offset / segmentLength * new Pnt2D(-segmentLine.Y, segmentLine.X);
                    segmentStarts.Add(segStart + off);
                    segmentStarts.Add(segStart - off);
                }

                foreach (Pnt segmentStart in segmentStarts)
                {
                    double tCircleMin, tCircleMax;
                    if (SegmentUtils.CutLineCircle(segmentStart, segmentLine, _center,
                                                   _radius * _radius,
                                                   out tCircleMin, out tCircleMax))
                    {
                        foreach (double t in new[] { tCircleMin, tCircleMax })
                        {
                            Pnt    dirPnt   = segmentStart + t * segmentLine - _center;
                            double dirAngle = Math.Atan2(dirPnt.Y, dirPnt.X);

                            if (IsInArcAngle(dirAngle))
                            {
                                tMin = Math.Min(tMin, t);
                                tMax = Math.Max(tMax, t);
                            }
                        }
                    }
                }
            }
        }
示例#7
0
        protected static bool Near([NotNull] Pnt p0,
                                   [NotNull] Pnt l0,
                                   [NotNull] Pnt p1,
                                   [NotNull] Pnt l1,
                                   double r2,
                                   double l12,
                                   ref double tMin, ref double tMax,
                                   ref NearSegment hullStartNear,
                                   ref NearSegment hullEndNear)
        {
            double cMin, cMax;

            double u0 = (p0 + tMin * l0 - p1) * l1 / l12;
            double u1 = (p0 + tMax * l0 - p1) * l1 / l12;

            if (u0 < 0)
            {
                if (SegmentUtils.CutLineCircle(p0, l0, p1, r2, out cMin, out cMax) == false)
                {
                    return(false);
                }

                hullStartNear = Near(cMin, cMax);

                // Debug.Assert(cMin > tMin); numerical exceptions possible
                tMin = cMin;
                if (u1 < 0)
                {
                    //Debug.Assert(cMax < tMax); numerical exceptions possible
                    tMax = cMax;
                }
            }
            else if (u0 > 1)
            {
                if (SegmentUtils.CutLineCircle(p0, l0, p1 + l1, r2, out cMin, out cMax) == false)
                {
                    return(false);
                }

                hullEndNear = Near(cMin, cMax);

                //Debug.Assert(cMin > tMin); numerical exceptions possible
                tMin = cMin;
                if (u1 > 1)
                {
                    //Debug.Assert(cMax < tMax); numerical exceptions possible
                    tMax = cMax;
                }
            }

            if (u1 < 0 && u0 >= 0)
            {
                if (SegmentUtils.CutLineCircle(p0, l0, p1, r2, out cMin, out cMax) == false)
                {
                    //throw new InvalidProgramException(
                    //	"error in software design assumption"); numerical exceptions possible
                    tMax          = tMin + u0 / (u0 - u1) * (tMax - tMin);
                    hullStartNear = Near(tMin, tMax);
                }
                else
                {
                    hullStartNear = Near(cMin, cMax);

                    //Debug.Assert(cMax < tMax); numerical exceptions possible
                    tMax = cMax;
                }
            }
            else if (u1 > 1 && u0 <= 1)
            {
                if (SegmentUtils.CutLineCircle(p0, l0, p1 + l1, r2, out cMin, out cMax) == false)
                {
                    //throw new InvalidProgramException(
                    //	"error in software design assumption"); numerical exceptions possible
                    tMax        = tMin + (1 - u0) / (u1 - u0) * (tMax - tMin);
                    hullEndNear = Near(tMin, tMax);
                }
                else
                {
                    hullEndNear = Near(cMin, cMax);

                    //Debug.Assert(cMax < tMax); numerical exceptions possible
                    tMax = cMax;
                }
            }

            return(true);
        }