示例#1
0
        public static bool SegmentToAboveArc(Segment seg, Arc arcAbove, ref double distance)
        {
            bool success = false;
            distance = double.MaxValue;
            List<Segment> listArc = arcAbove.Explode(20);

            foreach (Segment segArc in listArc)
            {
                double dist = 0.0f;
                if (PointToAboveSegment(seg.P0, segArc, ref dist) && dist > 0)
                {
                    distance = System.Math.Min(distance, dist);
                    success = true;
                }
                if (PointToAboveSegment(seg.P1, segArc, ref dist) && dist > 0)
                {
                    distance = System.Math.Min(distance, dist);
                    success = true;
                }
                if (PointToAboveSegment(segArc.P0, seg, ref dist) && dist < 0)
                {
                    distance = System.Math.Min(distance, -dist);
                    success = true;
                }
                if (PointToAboveSegment(segArc.P1, seg, ref dist) && dist < 0)
                {
                    distance = System.Math.Min(distance, -dist);
                    success = true;
                }
            }
            return success;
        }
示例#2
0
        public static bool PointToAboveSegment(Vector2D p, Segment seg, ref double distance)
        {
            double xMin = System.Math.Min(seg.P0.X, seg.P1.X);
            double xMax = System.Math.Max(seg.P0.X, seg.P1.X);

            if (p.X < xMin - MathFunctions.EpsilonF || p.X > xMax + MathFunctions.EpsilonF)
                return false;
            else
            {
                double yMin = System.Math.Min(seg.P0.Y, seg.P1.Y);
                double yMax = System.Math.Max(seg.P0.Y, seg.P1.Y);

                if (System.Math.Abs(seg.P1.X - seg.P0.X) < MathFunctions.EpsilonF)
                {
                    if (p.Y < yMin)
                        distance = yMin - p.Y;
                    else if (p.Y > yMax)
                        distance = yMax - p.Y;
                    else
                        distance = 0.0f;
                }
                else
                    distance = seg.P0.Y + (p.X - seg.P0.X) * (seg.P1.Y - seg.P0.Y) / (seg.P1.X - seg.P0.X) - p.Y;
                return true;
            }
        }
示例#3
0
 public static bool SegmentToAboveSegment(Segment seg, Segment segAbove, ref double distance)
 {
     bool success = false;
     distance = double.MaxValue;
     double dist = 0.0;
     if (PointToAboveSegment(seg.P0, segAbove, ref dist) && dist >= 0.0)
     {
         distance = System.Math.Min(distance, dist);
         success = true;
     }
     if (PointToAboveSegment(seg.P1, segAbove, ref dist) && dist >= 0.0)
     {
         distance = System.Math.Min(distance, dist);
         success = true;
     }
     if (PointToAboveSegment(segAbove.P0, seg, ref dist) && dist <= 0.0)
     {
         distance = System.Math.Min(distance, -dist);
         success = true;
     }
     if (PointToAboveSegment(segAbove.P1, seg, ref dist) && dist <= 0.0)
     {
         distance = System.Math.Min(distance, -dist);
         success = true;
     }
     return success;
 }
示例#4
0
 private static void TestArcToAboveSegment()
 {
     Arc arc = new Arc(Vector2D.Zero, 1.0f, -45.0f, -135.0f);
     Segment seg = new Segment(new Vector2D(-10.0f, 10.0f), new Vector2D(10.0f, 10.0f));
     double distance = 0.0;
     VerticalDistance.ArcToAboveSegment(arc, seg, ref distance);
     Console.WriteLine(string.Format("ArcToAboveSegment = {0}", distance));
 }
示例#5
0
		/// <summary>
		/// Calculates the squared distance between a point and a segment.
		/// </summary>
		/// <param name="point">A <see cref="Vector2D"/> instance.</param>
		/// <param name="segment">A <see cref="Segment"/> instance.</param>
		/// <returns>The squared distance between the point and the segment.</returns>
		public static double SquaredDistance(Vector2D point, Segment segment)
		{
            Vector2D D = segment.P1 - segment.P0;
            Vector2D diffPointP0 = point - segment.P0;
            double t = Vector2D.DotProduct(D, diffPointP0);

			if (t <= 0)
			{
				// segment.P0 is the closest to point.
                return Vector2D.DotProduct(diffPointP0, diffPointP0);
			}

            double DdD = Vector2D.DotProduct(D, D);
			if (t >= DdD)
			{
				// segment.P1 is the closest to point.
                Vector2D diffPointP1 = point - segment.P1;
                return Vector2D.DotProduct(diffPointP1, diffPointP1);
			}
			
			// Closest point is inside the segment.
            return Vector2D.DotProduct(diffPointP0, diffPointP0) - t * t / DdD;
		}
示例#6
0
        public static bool IntersectLines(Segment s0, Segment s1, out Intersection2D interObj)
        {
            //    (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
            //r = -----------------------------  (eqn 1)
            //    (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)

            //    (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
            //s = -----------------------------  (eqn 2)
            //    (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)

            double den = (s0.P1.X - s0.P0.X) * (s1.P1.Y - s1.P0.Y) - (s0.P1.Y - s0.P0.Y) * (s1.P1.X - s1.P0.X);
            double r = (s0.P0.Y - s1.P0.Y) * (s1.P1.X - s1.P0.X) - (s0.P0.X - s1.P0.X) * (s1.P1.Y - s1.P0.Y);
            double s = (s0.P0.Y - s1.P0.Y) * (s0.P1.X - s0.P0.X) - (s0.P0.X - s1.P0.X) * (s0.P1.Y - s0.P0.Y);

            // If the denominator in eqn 1 is zero, AB & CD are parallel
            if (System.Math.Abs(den) > MathFunctions.EpsilonF)
            {
                r /= den;
                s /= den;
                // Let P be the position vector of the intersection point, then
                // P=A+r(B-A)
                interObj = new Intersection2D(new Vector2D(s0.P0 + r * (s0.P1 - s0.P0)));
                return true;
            }
            else
            {
                // If the numerator in eqn 1 is also zero, AB & CD are collinear.
                if (System.Math.Abs(r) < MathFunctions.EpsilonF)
                {
                }
                else
                {
                }
            }
            interObj = new Intersection2D();
            return false;
        }
示例#7
0
		// segment intersection
		public Intersection2D(Segment seg)
		{
			_iType = IntersectionType.I2D_SEGMENT;
			_seg = seg;
		}
示例#8
0
		public static bool Intersect(Segment s0, Segment s1, out Intersection2D interObj)
		{ 
		//    (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
		//r = -----------------------------  (eqn 1)
		//    (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)

		//    (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
		//s = -----------------------------  (eqn 2)
		//    (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)

            double den = (s0.P1.X - s0.P0.X) * (s1.P1.Y - s1.P0.Y) - (s0.P1.Y - s0.P0.Y) * (s1.P1.X - s1.P0.X);
            double r = (s0.P0.Y - s1.P0.Y) * (s1.P1.X - s1.P0.X) - (s0.P0.X - s1.P0.X) * (s1.P1.Y - s1.P0.Y);
            double s = (s0.P0.Y - s1.P0.Y) * (s0.P1.X - s0.P0.X) - (s0.P0.X - s1.P0.X) * (s0.P1.Y - s0.P0.Y);

			// If the denominator in eqn 1 is zero, AB & CD are parallel
			if (System.Math.Abs(den) < MathFunctions.EpsilonF)
			{
				// If the numerator in eqn 1 is also zero, AB & CD are collinear.
				if (System.Math.Abs(r) < MathFunctions.EpsilonF)
				{
					Interval i0 = new Interval(Interval.Type.Closed, System.Math.Min(s0.P0.X, s0.P1.X), System.Math.Max(s0.P0.X, s0.P1.X));
					Interval i1 = new Interval(Interval.Type.Closed, System.Math.Min(s1.P0.X, s1.P1.X), System.Math.Max(s1.P0.X, s1.P1.X));
					
					// check if interval overlaps
					if ((i0.Max < i1.Min) || (i1.Max < i0.Min))
					{
						interObj = new Intersection2D();
						return false;
					}
					else
					{
						Interval i2 = new Interval(Interval.Type.Closed, System.Math.Max(i0.Min, i1.Min), System.Math.Min(i0.Max, i1.Max));
						interObj = new Intersection2D(new Segment());
						return true;
					}
				}
				else
				{
					interObj = new Intersection2D();
					return false;
				}
			}
			else
			{ 
				r /= den;
				s /= den;
				// Let P be the position vector of the intersection point, then
				// P=A+r(B-A)
				if (0 <= r && r <= 1 && 0 <= s && s <= 1)
				{
					interObj = new Intersection2D(new Vector2D(s0.P0+r*(s0.P1-s0.P0)));
					return true;
				}
			}
			interObj = new Intersection2D();
			return false;
		}
示例#9
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="factory"></param>
        public override void ProcessFactory(PicFactory factory)
        {
            // will only work with 2 segments
            if (null == _picSeg0 || null == _picSeg1)
                throw new NotImplementedException("Only segment entities are supported");

            // get inner segments
            Segment seg0 = new Segment(_picSeg0.Pt0, _picSeg0.Pt1);
            Segment seg1 = new Segment(_picSeg1.Pt0, _picSeg1.Pt1);

            // find line intersection and extend segments so that they intersect
            Intersection2D interobj;
            if (!IntersectMethods.IntersectLines(seg0, seg1, out interobj) || interobj == null || interobj.Type != Intersection2D.IntersectionType.I2D_POINT)  return;
            Vector2D ptExt = (Vector2D)interobj.Result;
            seg0 = extendSegment(seg0, ptExt);
            seg1 = extendSegment(seg1, ptExt);

            // create parallel segments
            Segment seg00, seg01;
            getParalleleSegments(seg0, _radius, out seg00, out seg01);
            Segment seg10, seg11;
            getParalleleSegments(seg1, _radius, out seg10, out seg11);

            // compute intersection
            if (IntersectMethods.Intersect(seg00, seg10, out interobj)) { }
            else if (IntersectMethods.Intersect(seg00, seg11, out interobj)) { }
            else if (IntersectMethods.Intersect(seg01, seg10, out interobj)) { }
            else if (IntersectMethods.Intersect(seg01, seg11, out interobj)) { }

            if (interobj == null || interobj.Type != Intersection2D.IntersectionType.I2D_POINT) return;
            Vector2D ptCenter = (Vector2D)interobj.Result;

            // get intersection of normal with seg0
            if (IntersectMethods.Intersect(seg0, new Segment(ptCenter, ptCenter + new Vector2D(-(seg0.P1 - seg0.P0).Y, (seg0.P1 - seg0.P0).X)), out interobj)) { }
            else if (IntersectMethods.Intersect(seg0, new Segment(ptCenter, ptCenter + new Vector2D((seg0.P1 - seg0.P0).Y, -(seg0.P1 - seg0.P0).X)), out interobj)) { }
            else return;
            if (interobj == null && interobj.Type != Intersection2D.IntersectionType.I2D_POINT) return;
            Vector2D pt0 = (Vector2D)interobj.Result;

            if (IntersectMethods.Intersect(seg1, new Segment(ptCenter, ptCenter + new Vector2D(-(seg1.P1 - seg1.P0).Y, (seg1.P1 - seg1.P0).X)), out interobj)) { }
            else if (IntersectMethods.Intersect(seg1, new Segment(ptCenter, ptCenter + new Vector2D((seg1.P1 - seg1.P0).Y, -(seg1.P1 - seg1.P0).X)), out interobj)) { }
            else return;
            if (interobj == null && interobj.Type != Intersection2D.IntersectionType.I2D_POINT) return;
            Vector2D pt1 = (Vector2D)interobj.Result;

            // intersection of 2D segments
            if (!IntersectMethods.Intersect(seg0, seg1, out interobj)) return;
            if (interobj == null && interobj.Type != Intersection2D.IntersectionType.I2D_POINT) return;
            Vector2D ptInter = (Vector2D)interobj.Result;

            // modify segments
            if ((seg0.P0 - ptInter).GetLength() < (seg0.P1 - ptInter).GetLength())
            {
                _picSeg0.Pt0 = pt0;
                _picSeg0.Pt1 = seg0.P1;
            }
            else
            {
                _picSeg0.Pt0 = pt0;
                _picSeg0.Pt1 = seg0.P0;
            }

            if ((seg1.P0 - ptInter).GetLength() < (seg1.P1 - ptInter).GetLength())
            {
                _picSeg1.Pt0 = pt1;
                _picSeg1.Pt1 = seg1.P1;
            }
            else
            {
                _picSeg1.Pt0 = pt1;
                _picSeg1.Pt1 = seg1.P0;
            }

            // create new arc of circle
            if (Vector2D.KrossProduct(pt0 - ptCenter, pt1 - ptCenter) > 0) // go from pt0 to pt1
                factory.AddArc(_picSeg0.LineType, _picSeg0.Group, _picSeg0.Layer, ptCenter, pt0, pt1);
            else // from pt1 to pt0
                factory.AddArc(_picSeg0.LineType, _picSeg0.Group, _picSeg0.Layer, ptCenter, pt1, pt0);
        }
示例#10
0
 /// <summary>
 /// get an extended segment using given point if it is not already on the segment
 /// </summary>
 /// <param name="segInit">initial segment</param>
 /// <param name="pt">point to use in order to extend segment</param>
 /// <returns>a segment which contains both the initial segment and the given point</returns>
 static private Segment extendSegment(Segment segInit, Vector2D pt)
 { 
     Vector2D vecSeg = segInit.P1 - segInit.P0;
     double prod0 = Vector2D.DotProduct(segInit.P0 - pt, vecSeg);
     double prod1 = Vector2D.DotProduct(segInit.P1 - pt, vecSeg);
     if (prod0 > 0 && prod1 > 0)
         return new Segment(pt, segInit.P1); // extend segment on the P0 side
     else if (prod0 < 0 && prod1 < 0)
         return new Segment(pt, segInit.P0); // extend segment on the P1 side
     else
         return new Segment(segInit);    // do not need to extend segment
 }
示例#11
0
        /// <summary>
        /// compute the two parallel segments at a certain distance 
        /// </summary>
        /// <param name="segInit">initial segment</param>
        /// <param name="dist">distance</param>
        /// <param name="s0">first segment (out)</param>
        /// <param name="s1">second segment (out)</param>
        static private void getParalleleSegments(Segment segInit, double dist, out Segment s0, out Segment s1)
        {
            // get dir vector
            Vector2D vecDir = segInit.P1 - segInit.P0;
            vecDir /= vecDir.GetLength();

            // vecNormal
            Vector2D vecNorm = new Vector2D(-vecDir.Y, vecDir.X);

            // compute segment
            Vector2D p00 = segInit.P0 + dist * vecNorm;
            s0 = new Segment(p00, p00 + segInit.P1 - segInit.P0);
            Vector2D p10 = segInit.P0 - dist * vecNorm;
            s1 = new Segment(p10, p10 + segInit.P1 - segInit.P0);
        }
示例#12
0
        public override void ProcessFactory(PicFactory factory)
        {
            // initialization
            _segList.Clear();
            _box = new Box2D();
            _area = 0.0;

            // build list of segments with entities that belongs to group
            factory.ProcessToolAllEntities(this);
            _box.AddMarginRatio(0.2);

            // exit if no of segments exceeds MAXSEG
            int maxSeg = Pic.Factory2D.Properties.Settings.Default.AreaMaxNoSegments;
            if (_segList.Count > maxSeg)
                throw new PicToolTooLongException(string.Format("No of segments exceeds {0}", maxSeg));

            // compute actual step size
            uint iNoStep = (uint)(_box.Width / _stepSize);
            iNoStep = Math.Min(iNoStep, _iNoStepMax);
            double stepDefault = _box.Width / iNoStep;

            // compute area
            for (int i = 0; i < iNoStep; ++i)
            {
                double xh = _box.XMin + i * stepDefault;
                int nby = 1;
                double stepCurrent = stepDefault;
                List<double> tabyh = new List<double>();

                tabyh.Add(double.MaxValue);

                bool bAgain = false;
                do
                {
                    bAgain = false;
                    stepCurrent = stepDefault;

                    foreach (Segment segTemp in _segList)
                    {
                        Segment seg;
                        if (segTemp.P0.X <= segTemp.P1.X)
                            seg = segTemp;
                        else
                            seg = new Segment(segTemp.P1, segTemp.P0);

                        if (xh >= seg.P0.X && xh <= seg.P1.X)
                        {
                            // cas intersections confondues
                            if ((Math.Abs(xh - seg.P0.X) < 0.001) || (Math.Abs(seg.P1.X - xh) < 0.001))
                            {
                                // restart loop from the beginning
                                nby = 1;
                                tabyh[0] = double.MaxValue;
                                stepCurrent = 0.9 * stepDefault;
                                xh -= stepDefault * 0.1;
                                bAgain = true;
                                break;
                            }
                            else
                            {
                                double yh = seg.P0.Y + (xh - seg.P0.X) * ((seg.P1.Y - seg.P0.Y) / (seg.P1.X - seg.P0.X));
                                tabyh.Add(yh);
                            }
                        }
                    }
                }
                while (bAgain);

                tabyh.Sort();
                nby = tabyh.Count;

                // increment area
                if (nby > 1 && (nby % 2 != 0))
                {
                    for (int l = 0; l < nby - 1; l += 2)
                    {
                        _area = _area + stepCurrent * (tabyh[l + 1] - tabyh[l]);
                    }
                }
            }
        }
示例#13
0
		/// <summary>
		/// Calculates the distance between two segments.
		/// </summary>
		/// <param name="s0">A <see cref="Segment"/> instance.</param>
		/// <param name="s1">A <see cref="Segment"/> instance.</param>
		/// <returns>Returns the distance between two segments.</returns>
		public static float Distance(Segment s0, Segment s1)
		{
			throw new NotImplementedException();
		}
示例#14
0
		/// <summary>
		/// Calculates the squared distance between a point and a segment.
		/// </summary>
		/// <param name="point">A <see cref="Vector2D"/> instance.</param>
		/// <param name="segment">A <see cref="Segment"/> instance.</param>
		/// <returns>The squared distance between the point and the segment.</returns>
		public static double Distance(Vector2D point, Segment segment)
		{
			return System.Math.Sqrt(SquaredDistance(point, segment));
		}
示例#15
0
		/// <summary>
		/// Initializes a new instance of the <see cref="Segment"/> class using an existing <see cref="Segment"/> instance.
		/// </summary>
		/// <param name="segment">A <see cref="Segment"/> instance.</param>
		public Segment(Segment segment)
		{
			_p0 = segment.P0;
			_p1 = segment.P1;
		}
示例#16
0
        public static bool Intersect(Segment seg, Ray ray, out Intersection2D interObj)
        {
            //    (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
            //r = -----------------------------  (eqn 1)
            //    (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)

            //    (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
            //s = -----------------------------  (eqn 2)
            //    (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)

            double den = (seg.P1.X - seg.P0.X) * ray.Direction.Y - (seg.P1.Y - seg.P0.Y) * ray.Direction.X;
            double r = (seg.P0.Y - ray.Origin.Y) * ((ray.Origin + ray.Direction).X - ray.Origin.X) - (seg.P0.X - ray.Origin.X) * ((ray.Origin + ray.Direction).Y - ray.Origin.Y);

            // If the denominator in eqn 1 is zero, AB & CD are parallel
            if (System.Math.Abs(den) < MathFunctions.EpsilonF)
            {
                // If the numerator in eqn 1 is also zero, AB & CD are collinear.
                if (System.Math.Abs(r) < MathFunctions.EpsilonF)
                {
                    interObj = new Intersection2D(new Segment(seg));
                    return true;
                }
                else
                {
                    interObj = new Intersection2D();
                    return false;
                }
            }
            else
            {
                r /= den;
                // Let P be the position vector of the intersection point, then
                // P=A+r(B-A)
                if (0 <= r && r <= 1)
                {
                    interObj = new Intersection2D(new Vector2D(seg.P0 + r * (seg.P1 - seg.P0)));
                    return true;
                }
            }
            interObj = new Intersection2D();
            return false;
        }