예제 #1
0
        public bool Cut(HullLineArc line, ref double tMin, ref double tMax)
        {
            double angS = line.StartDirection;
            double r    = line.Radius;

            // Handle start point of line-arc
            var   aS         = new Pnt2D(r * Math.Cos(angS), r * Math.Sin(angS));
            Lin2D s          = line.Lin.GetParallel(aS);
            bool  intersects = CutLineThis(s.Ps, s.L, ref tMin, ref tMax);

            // Handle end point of line-arc
            double angE = angS + line.Angle;
            var    aE   = new Pnt2D(r * Math.Cos(angE), r * Math.Sin(angE));
            Lin2D  e    = line.Lin.GetParallel(aE);

            intersects |= CutLineThis(e.Ps, e.L, ref tMin, ref tMax);

            if (Angle.HasValue)
            {
                intersects |=
                    CutLineEndpoint(StartDirection + Angle.Value, line, ref tMin, ref tMax);

                intersects |= CutLineEndpoint(StartDirection, line, ref tMin, ref tMax);
            }

            intersects |= CutLineThis(line.Lin.Ps, line.Lin.L, ref tMin, ref tMax,
                                      new SignedHullLineArc(line, deflate: false));
            intersects |= CutLineThis(line.Lin.Ps, line.Lin.L, ref tMin, ref tMax,
                                      new SignedHullLineArc(line, deflate: true));
            return(intersects);
        }
예제 #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 static bool ValidateIntersects(Pnt center, HullLineArc line, double t,
                                               ref double tMin,
                                               ref double tMax)
        {
            Pnt    dir   = center - (line.Lin.Ps + t * line.Lin.L);
            double angle = Math.Atan2(dir.Y, dir.X);

            if (!IsInArcAngle(angle, line.StartDirection, line.Angle))
            {
                return(false);
            }

            tMin = Math.Min(tMin, t);
            tMax = Math.Max(tMax, t);
            return(true);
        }
예제 #4
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);
        }
예제 #5
0
        private static bool IsPointInArcDirection(Pnt p, HullLineArc line, double lineAt,
                                                  ref double tMin, ref double tMax)
        {
            Pnt    pointAt  = line.Lin.Ps + lineAt * line.Lin.L;
            Pnt    dirToP   = p - pointAt;
            double minAngle = GetNormedAngle(Math.Atan2(dirToP.Y, dirToP.X) - line.StartDirection);
            double arcAngle = GetNormedAngle(line.Angle);

            if (minAngle >= arcAngle)
            {
                return(false);
            }

            tMin = Math.Min(tMin, lineAt);
            tMax = Math.Max(tMax, lineAt);
            return(true);
        }
예제 #6
0
        public bool Cut(HullLineArc line, ref double tMin, ref double tMax)
        {
            double angS = line.StartDirection;
            double r    = line.Radius;

            // Handle start point of arc
            var   aS         = new Pnt2D(r * Math.Cos(angS), r * Math.Sin(angS));
            Lin2D s          = line.Lin.GetParallel(aS);
            bool  intersects = CutLin(_lin, s, ref tMin, ref tMax);

            // Handle end point of arc
            double angE = angS + line.Angle;
            var    aE   = new Pnt2D(r * Math.Cos(angE), r * Math.Sin(angE));
            Lin2D  e    = line.Lin.GetParallel(aE);

            intersects |= CutLin(_lin, e, ref tMin, ref tMax);

            // Handle this start/end point
            intersects |= CutArcLine(_lin.Ps, line, ref tMin, ref tMax);
            intersects |= CutArcLine(_lin.Pe, line, ref tMin, ref tMax);

            // handle sides
            double arcAngle  = GetNormedAngle(line.Angle);
            Pnt    normal    = _lin.LNormal;
            double normalDir = _lin.DirectionAngle + Math.PI / 2;

            // handle left side
            if (GetNormedAngle(normalDir - line.StartDirection) < arcAngle)
            {
                intersects |= CutLin(_lin.GetParallel(r * normal), line.Lin, ref tMin, ref tMax);
            }

            // handle right side
            if (GetNormedAngle(normalDir + Math.PI - line.StartDirection) < arcAngle)
            {
                intersects |= CutLin(_lin.GetParallel(-r * normal), line.Lin, ref tMin, ref tMax);
            }

            return(intersects);
        }
예제 #7
0
 public SignedHullLineArc(HullLineArc arc, bool deflate)
 {
     Arc     = arc;
     Deflate = deflate;
 }