Esempio n. 1
0
        protected override void Calculate <BaseSegment>(int index, BaseSegment segment)
        {
            var width  = 1.0f;
            var height = 1.0f;

            segment.Height = height / (CountY);
            segment.Width  = width / (CountX);

            SegmentPoint[] lastPoints = new SegmentPoint[4];
            if (index != 0 && index % CountX != 0)
            {
                lastPoints = segments.FirstOrDefault(x => x.Index == index - 1).Points;
            }

            int Row = (int)(segment.Index / (CountX));
            int Col = (int)(segment.Index / (CountY));

            if (lastPoints[1] == null)
            {
                lastPoints[1] = new SegmentPoint(0, segment.Height * Row);
            }
            if (lastPoints[2] == null)
            {
                lastPoints[2] = new SegmentPoint(lastPoints[1].X, lastPoints[1].Y + segment.Height);
            }

            var startPoint2 = new SegmentPoint(lastPoints[1].X + segment.Width, lastPoints[1].Y);
            var startPoint3 = new SegmentPoint(lastPoints[2].X + segment.Width, lastPoints[2].Y);

            segment.Points    = new SegmentPoint[4];
            segment.Points[0] = (lastPoints[1]);
            segment.Points[1] = (startPoint2);
            segment.Points[2] = (startPoint3);
            segment.Points[3] = (lastPoints[2]);
        }
Esempio n. 2
0
 /// <summary>
 /// Default error function is evaluating how far we're from the last point
 /// given the current segment length.
 /// </summary>
 /// <param name="curve">Point curve.</param>
 /// <param name="curr">Current segment point.</param>
 /// <param name="next">Next segment point.</param>
 /// <param name="segmentType">Segment type.</param>
 /// <returns>0.0f unless segmentType == last, then distance from next to last point in list.</returns>
 public static float DefaultErrorFunc(PointCurve curve, SegmentPoint curr, SegmentPoint next, SegmentType segmentType)
 {
     if (segmentType == SegmentType.Last)
     {
         return(Mathf.Sign(1.0f - next.Time) * Vector3.Distance(next.Point, curve.Evaluate(1.0f).Point));
     }
     return(0.0f);
 }
Esempio n. 3
0
 public SegmentLine(SegmentPoint A, SegmentPoint B, OverflowType LeftOverflowAction = OverflowType.AsLine, OverflowType RightOverflowAction = OverflowType.AsLine)
 {
     this.A = A;
     this.B = B;
     this.LOverflowAction = LeftOverflowAction;
     this.ROverflowAction = RightOverflowAction;
     InitParams();
 }
Esempio n. 4
0
 public void CloneFrom(ref Segment segment)
 {
     Tl               = segment.Tl;
     Tr               = segment.Tr;
     Br               = segment.Br;
     Bl               = segment.Bl;
     Point            = segment.Point;
     NextPoint        = segment.NextPoint;
     HasFusedPoint    = segment.HasFusedPoint;
     ShouldFuseBottom = segment.ShouldFuseBottom;
     Angle            = segment.Angle;
 }
 public void cloneFrom(ref Segment segment)
 {
     tl               = segment.tl;
     tr               = segment.tr;
     br               = segment.br;
     bl               = segment.bl;
     point            = segment.point;
     nextPoint        = segment.nextPoint;
     hasFusedPoint    = segment.hasFusedPoint;
     shouldFuseBottom = segment.shouldFuseBottom;
     angle            = segment.angle;
 }
            public void setPoints(ref SegmentPoint point, ref SegmentPoint nextPoint)
            {
                angle          = 0;
                this.point     = point;
                this.nextPoint = nextPoint;

                // rotate 90 degrees before calculating and cache cos/sin
                var radians = Mathf.atan2(nextPoint.position.Y - point.position.Y, nextPoint.position.X - point.position.X);

                radians += MathHelper.PiOver2;
                var halfCos = Mathf.cos(radians) * 0.5f;
                var halfSin = Mathf.sin(radians) * 0.5f;

                tl = point.position - new Vector2(point.width * halfCos, point.width * halfSin);
                tr = nextPoint.position - new Vector2(nextPoint.width * halfCos, nextPoint.width * halfSin);
                br = nextPoint.position + new Vector2(nextPoint.width * halfCos, nextPoint.width * halfSin);
                bl = point.position + new Vector2(point.width * halfCos, point.width * halfSin);
            }
Esempio n. 7
0
            public void SetPoints(ref SegmentPoint point, ref SegmentPoint nextPoint)
            {
                Angle          = 0;
                this.Point     = point;
                this.NextPoint = nextPoint;

                // rotate 90 degrees before calculating and cache cos/sin
                var radians = Mathf.Atan2(nextPoint.Position.Y - point.Position.Y, nextPoint.Position.X - point.Position.X);

                radians += MathHelper.PiOver2;
                var halfCos = Mathf.Cos(radians) * 0.5f;
                var halfSin = Mathf.Sin(radians) * 0.5f;

                Tl = point.Position - new Vector2(point.Width * halfCos, point.Width * halfSin);
                Tr = nextPoint.Position - new Vector2(nextPoint.Width * halfCos, nextPoint.Width * halfSin);
                Br = nextPoint.Position + new Vector2(nextPoint.Width * halfCos, nextPoint.Width * halfSin);
                Bl = point.Position + new Vector2(point.Width * halfCos, point.Width * halfSin);
            }
Esempio n. 8
0
        protected void Calculate(int row, int col, BaseSegment segment)
        {
            segment.Height = CONSTS.COMPARING_MARKER_DIAMETER / CountY;
            segment.Width  = CONSTS.COMPARING_MARKER_DIAMETER / CountX;

            SegmentPoint[] lastPoints = new SegmentPoint[4];

            if (col != 0)
            {
                lastPoints = segments.FirstOrDefault(x => x.Index == segment.Index - 1).Points;
            }

            int Row = row;
            int Col = col;

            segment.Points = new SegmentPoint[4];

            if (lastPoints == null || lastPoints[1] == null && lastPoints[2] == null) //nov red
            {
                segment.Points[0] = new SegmentPoint(CONSTS.COMPARING_MARKER_DIAMETER / 2 - (segment.Width / 2) * Row, segment.Height * Row);
                segment.Points[1] = segment.Points[0];
                segment.Points[2] = new SegmentPoint(segment.Points[0].X + segment.Width / 2, segment.Points[0].Y + segment.Height);
                segment.Points[3] = new SegmentPoint(segment.Points[0].X - segment.Width / 2, segment.Points[0].Y + segment.Height);
            }
            else
            {
                if (Col % 2 == 0)                                                                           //vseki 4eten element (pravilen)
                {
                    segment.Points[0] = lastPoints[1];                                                      //gore
                    segment.Points[1] = segment.Points[0];                                                  //gore
                    segment.Points[2] = new SegmentPoint(lastPoints[2].X + segment.Width, lastPoints[2].Y); //dolu
                    segment.Points[3] = lastPoints[2];                                                      //dolu
                }
                else//(oburnat nadolu)
                {
                    segment.Points[0] = lastPoints[0];                                                      //gore
                    segment.Points[1] = new SegmentPoint(lastPoints[0].X + segment.Width, lastPoints[0].Y); //gore
                    segment.Points[2] = lastPoints[2];                                                      //dolu
                    segment.Points[3] = segment.Points[2];                                                  //dolu
                }
            }
        }
        protected override void Calculate <BaseSegment>(int index, BaseSegment segment)
        {
            SegmentPoint[] lastPoints = new SegmentPoint[4];
            if (index != 0 && index % CountX != 0)
            {
                lastPoints = segments.FirstOrDefault(x => x.Index == index - 1).Points;
            }

            segment.Height = (CONSTS.COMPARING_MARKER_DIAMETER / 2f) / (CountY + 1);

            float AngleGrad = 360f / CountX;
            int   Row       = (int)(segment.Index / (CountX));



            if (lastPoints[1] == null)
            {
                lastPoints[1] = new SegmentPoint(CONSTS.COMPARING_MARKER_DIAMETER / 2.0, CONSTS.COMPARING_MARKER_DIAMETER - segment.Height - segment.Height * Row);
            }
            if (lastPoints[2] == null)
            {
                lastPoints[2] = new SegmentPoint(CONSTS.COMPARING_MARKER_DIAMETER / 2.0, CONSTS.COMPARING_MARKER_DIAMETER - segment.Height * Row);
            }

            segment.Points = new SegmentPoint[4];

            var startPoint2 = new SegmentPoint(0, 0);
            var startPoint3 = new SegmentPoint(0, 0);
            var startPoint1 = lastPoints[1];
            var startPoint4 = lastPoints[2];


            startPoint2.rotatePoint(startPoint1, new SegmentPoint(CONSTS.COMPARING_MARKER_DIAMETER / 2, CONSTS.COMPARING_MARKER_DIAMETER / 2), AngleGrad / (180 / Math.PI));
            startPoint3.rotatePoint(startPoint4, new SegmentPoint(CONSTS.COMPARING_MARKER_DIAMETER / 2, CONSTS.COMPARING_MARKER_DIAMETER / 2), AngleGrad / (180 / Math.PI));

            segment.Points[0] = (lastPoints[1]);
            segment.Points[1] = (startPoint2);
            segment.Points[2] = (startPoint3);
            segment.Points[3] = (lastPoints[2]);
        }
Esempio n. 10
0
        /// <summary>
        /// Evaluate curve at given time [0, 1].
        /// </summary>
        /// <param name="t">Time along curve [0, 1].</param>
        /// <returns>Segment point at given time.</returns>
        public SegmentPoint Evaluate(float t)
        {
            if (m_points.Count < 2)
            {
                Debug.LogWarning("PointCurve.Evaluate called with an undefined curve #points < 2.");
                return(default(SegmentPoint));
            }

            if (m_points.Count != m_time.Count && !Finalize())
            {
                Debug.LogWarning("PointCurve.Finalize failed - length of curve is undefined: " + TotalLength);
                return(default(SegmentPoint));
            }

            var index = FindIndex(t);

            if (index + 1 >= m_points.Count)
            {
                index = m_points.Count - 2;
            }

            var segment = new SegmentPoint();

            segment.Begin = m_points[index];
            segment.End   = m_points[index + 1];
            segment.Time  = t;
            if (m_time[index] == m_time[index + 1])
            {
                segment.LocalTime = 1.0f;
                segment.Point     = segment.End;
            }
            else
            {
                segment.LocalTime = (t - m_time[index]) / (m_time[index + 1] - m_time[index]);
                segment.Point     = segment.Begin + segment.LocalTime * (segment.End - segment.Begin);
            }

            return(segment);
        }
Esempio n. 11
0
    public static List <SegmentPath> segments_to_paths__sorted_list(List <Segment> segments, float distMax = 1e-10f)
    {
        List <SegmentPath> paths = new List <SegmentPath>();

        //create a linked list of points sorted by x coordinate
        List <SegmentPoint> segmentPoints = new List <SegmentPoint>();

        foreach (Segment s in segments)
        {
            SegmentPoint sp0 = new SegmentPoint(s.p[0], null);
            SegmentPoint sp1 = new SegmentPoint(s.p[1], sp0);
            sp0.otherSegmentPoint = sp1;
            segmentPoints.Add(sp0);
            segmentPoints.Add(sp1);
        }
        segmentPoints.Sort();
        for (int i = 0; i < segmentPoints.Count - 1; i++)
        {
            segmentPoints[i].next = segmentPoints[i + 1];
        }
        for (int i = 1; i < segmentPoints.Count; i++)
        {
            segmentPoints[i].prev = segmentPoints[i - 1];
        }

        //process each segment
        foreach (SegmentPoint spMainLoop in segmentPoints)
        {
            //only process segments that are alive
            if (!spMainLoop.alive)
            {
                continue;
            }

            //start a new path with this segment
            spMainLoop.alive = false;
            spMainLoop.otherSegmentPoint.alive = false;
            SegmentPath path = new SegmentPath(spMainLoop.point, spMainLoop.otherSegmentPoint.point);
            paths.Add(path);

            //append/prepend points to path
            SegmentPoint spPath; //the current path point to append/prepend to
            SegmentPoint spTry;  //the point that is examined to be appended/prepended
            bool         found;
            //find points to APPEND to path
            spPath = spMainLoop.otherSegmentPoint; //APPEND (last point of path)
            do
            {
                found = false;
                //go FORWARD through the sorted list
                spTry = spPath.next;                                   //FORWARD
                while (spTry != null && spTry.X - spPath.X <= distMax) //FORWARD try.x >= path.x
                {
                    if (spTry.alive && Vector2F.DistanceManhattan(spPath.point, spTry.point) <= distMax)
                    {
                        spTry.alive = false;
                        spTry.otherSegmentPoint.alive = false;
                        spPath = spTry.otherSegmentPoint;
                        path.p.AddLast(spPath.point); //APPEND
                        found = true;
                        break;
                    }
                    else
                    {
                        spTry = spTry.next; //FORWARD
                    }
                }
                //if nothing found, then go BACKWARD through the sorted list
                if (!found)
                {
                    spTry = spPath.prev;                                   //BACKWARD
                    while (spTry != null && spPath.X - spTry.X <= distMax) //BACKWARD path.x >= try.x
                    {
                        if (spTry.alive && Vector2F.DistanceManhattan(spPath.point, spTry.point) <= distMax)
                        {
                            spTry.alive = false;
                            spTry.otherSegmentPoint.alive = false;
                            spPath = spTry.otherSegmentPoint;
                            path.p.AddLast(spPath.point); //APPEND
                            found = true;
                            break;
                        }
                        else
                        {
                            spTry = spTry.prev; //BACKWARD
                        }
                    }
                }
            } while (found);

            //find points to PREPEND to path
            spPath = spMainLoop; //PREPEND (first point of path)
            do
            {
                found = false;
                //go FORWARD through the sorted list
                spTry = spPath.next;                                   //FORWARD
                while (spTry != null && spTry.X - spPath.X <= distMax) //FORWARD try.x >= path.x
                {
                    if (spTry.alive && Vector2F.DistanceManhattan(spPath.point, spTry.point) <= distMax)
                    {
                        spTry.alive = false;
                        spTry.otherSegmentPoint.alive = false;
                        spPath = spTry.otherSegmentPoint;
                        path.p.AddFirst(spPath.point); //PREPEND
                        found = true;
                        break;
                    }
                    else
                    {
                        spTry = spTry.next; //FORWARD
                    }
                }
                //if nothing found, then go BACKWARD through the sorted list
                if (!found)
                {
                    spTry = spPath.prev;                                   //BACKWARD
                    while (spTry != null && spPath.X - spTry.X <= distMax) //BACKWARD path.x >= try.x
                    {
                        if (spTry.alive && Vector2F.DistanceManhattan(spPath.point, spTry.point) <= distMax)
                        {
                            spTry.alive = false;
                            spTry.otherSegmentPoint.alive = false;
                            spPath = spTry.otherSegmentPoint;
                            path.p.AddFirst(spPath.point); //PREPEND
                            found = true;
                            break;
                        }
                        else
                        {
                            spTry = spTry.prev; //BACKWARD
                        }
                    }
                }
            } while (found);
        }

        return(paths);
    }
        void calculateVertices()
        {
            if (!_areVertsDirty || _points.length < 2)
            {
                return;
            }

            _areVertsDirty = false;
            _indices.reset();
            _vertices.reset();

            var maxX = float.MinValue;
            var minX = float.MaxValue;
            var maxY = float.MinValue;
            var minY = float.MaxValue;

            if (_useStartEndWidths)
            {
                _maxWidth = System.Math.Max(_startWidth, _endWidth);
            }

            // calculate line length first and simulataneously get our min/max points for the bounds
            var lineLength   = 0f;
            var halfMaxWidth = _maxWidth * 0.5f;

            _points.buffer[0].lengthFromPreviousPoint = 0;
            for (var i = 0; i < _points.length - 1; i++)
            {
                var distance = Vector2.Distance(_points.buffer[i].position, _points.buffer[i + 1].position);
                _points.buffer[i + 1].lengthFromPreviousPoint = distance;
                lineLength += distance;

                maxX = Mathf.maxOf(maxX, _points.buffer[i].position.X + halfMaxWidth, _points.buffer[i + 1].position.X + halfMaxWidth);
                minX = Mathf.minOf(minX, _points.buffer[i].position.X - halfMaxWidth, _points.buffer[i + 1].position.X - halfMaxWidth);
                maxY = Mathf.maxOf(maxY, _points.buffer[i].position.Y + halfMaxWidth, _points.buffer[i + 1].position.Y + halfMaxWidth);
                minY = Mathf.minOf(minY, _points.buffer[i].position.Y - halfMaxWidth, _points.buffer[i + 1].position.Y - halfMaxWidth);
            }

            _bounds.x      = minX;
            _bounds.y      = minY;
            _bounds.width  = maxX - minX;
            _bounds.height = maxY - minY;

            // special case: single segment
            if (_points.length == 2)
            {
                if (_useStartEndWidths)
                {
                    _points.buffer[0].width = _startWidth;
                    _points.buffer[1].width = _endWidth;
                }

                if (_useStartEndColors)
                {
                    _points.buffer[0].color = _startColor;
                    _points.buffer[1].color = _endColor;
                }

                _firstSegment.setPoints(ref _points.buffer[0], ref _points.buffer[1]);
                addSingleSegmentLine(ref _firstSegment, _points.buffer[1].color);
                return;
            }

            var distanceSoFar = 0f;
            var fusedPoint    = Vector2.Zero;
            var vertIndex     = 0;
            var thirdPoint    = new SegmentPoint();

            for (var i = 0; i < _points.length - 1; i++)
            {
                var firstPoint  = _points.buffer[i];
                var secondPoint = _points.buffer[i + 1];

                var hasThirdPoint = _points.length > i + 2;
                if (hasThirdPoint)
                {
                    thirdPoint = _points.buffer[i + 2];
                }

                // we need the distance along the line of both the first and second points. distanceSoFar will always be for the furthest point
                // which is the previous point before adding the current segment distance.
                var firstPointDistance = distanceSoFar;
                distanceSoFar += secondPoint.lengthFromPreviousPoint;

                var firstPointRatio  = firstPointDistance / lineLength;
                var secondPointRatio = distanceSoFar / lineLength;
                var thirdPointRatio  = 0f;
                if (hasThirdPoint)
                {
                    thirdPointRatio = (distanceSoFar + thirdPoint.lengthFromPreviousPoint) / lineLength;
                }

                if (_useStartEndColors)
                {
                    ColorExt.lerp(ref _startColor, ref _endColor, out firstPoint.color, firstPointRatio);
                    ColorExt.lerp(ref _startColor, ref _endColor, out secondPoint.color, secondPointRatio);

                    if (hasThirdPoint)
                    {
                        ColorExt.lerp(ref _startColor, ref _endColor, out thirdPoint.color, thirdPointRatio);
                    }
                }

                if (_useStartEndWidths)
                {
                    firstPoint.width  = Mathf.lerp(_startWidth, _endWidth, firstPointRatio);
                    secondPoint.width = Mathf.lerp(_startWidth, _endWidth, secondPointRatio);

                    if (hasThirdPoint)
                    {
                        thirdPoint.width = Mathf.lerp(_startWidth, _endWidth, thirdPointRatio);
                    }
                }


                if (i == 0)
                {
                    _firstSegment.setPoints(ref firstPoint, ref secondPoint);
                    _secondSegment.setPoints(ref secondPoint, ref thirdPoint);
                }
                else
                {
                    Utils.swap(ref _firstSegment, ref _secondSegment);
                    if (hasThirdPoint)
                    {
                        _secondSegment.setPoints(ref secondPoint, ref thirdPoint);
                    }
                }

                // dont recalculate the fusedPoint for the last segment since there will be no third point to work with
                if (hasThirdPoint)
                {
                    var shouldFuseBottom = Vector2Ext.isTriangleCCW(firstPoint.position, secondPoint.position, thirdPoint.position);
                    _secondSegment.setFusedData(shouldFuseBottom, ref _firstSegment);
                }

                // special care needs to be take with the first segment since it has a different vert count
                if (i == 0)
                {
                    addFirstSegment(ref _firstSegment, ref _secondSegment, ref vertIndex);
                }
                else
                {
                    addSegment(ref _firstSegment, ref vertIndex);
                }

                _lastSegment.cloneFrom(ref _firstSegment);
            }
        }
Esempio n. 13
0
		void calculateVertices()
		{
			if( !_areVertsDirty || _points.length < 2 )
				return;

			_areVertsDirty = false;
			_indices.reset();
			_vertices.reset();

			var maxX = float.MinValue;
			var minX = float.MaxValue;
			var maxY = float.MinValue;
			var minY = float.MaxValue;

			if( _useStartEndWidths )
				_maxWidth = System.Math.Max( _startWidth, _endWidth );

			// calculate line length first and simulataneously get our min/max points for the bounds
			var lineLength = 0f;
			var halfMaxWidth = _maxWidth * 0.5f;
			_points.buffer[0].lengthFromPreviousPoint = 0;
			for( var i = 0; i < _points.length - 1; i++ )
			{
				var distance = Vector2.Distance( _points.buffer[i].position, _points.buffer[i + 1].position );
				_points.buffer[i + 1].lengthFromPreviousPoint = distance;
				lineLength += distance;

				maxX = Mathf.maxOf( maxX, _points.buffer[i].position.X + halfMaxWidth, _points.buffer[i + 1].position.X + halfMaxWidth );
				minX = Mathf.minOf( minX, _points.buffer[i].position.X - halfMaxWidth, _points.buffer[i + 1].position.X - halfMaxWidth );
				maxY = Mathf.maxOf( maxY, _points.buffer[i].position.Y + halfMaxWidth, _points.buffer[i + 1].position.Y + halfMaxWidth );
				minY = Mathf.minOf( minY, _points.buffer[i].position.Y - halfMaxWidth, _points.buffer[i + 1].position.Y - halfMaxWidth );
			}

			_bounds.x = minX;
			_bounds.y = minY;
			_bounds.width = maxX - minX;
			_bounds.height = maxY - minY;

			// special case: single segment
			if( _points.length == 2 )
			{
				if( _useStartEndWidths )
				{
					_points.buffer[0].width = _startWidth;
					_points.buffer[1].width = _endWidth;
				}

				if( _useStartEndColors )
				{
					_points.buffer[0].color = _startColor;
					_points.buffer[1].color = _endColor;
				}

				_firstSegment.setPoints( ref _points.buffer[0], ref _points.buffer[1] );
				addSingleSegmentLine( ref _firstSegment, _points.buffer[1].color);
				return;
			}

			var distanceSoFar = 0f;
			var fusedPoint = Vector2.Zero;
			var vertIndex = 0;
			var thirdPoint = new SegmentPoint();

			for( var i = 0; i < _points.length - 1; i++ )
			{
				var firstPoint = _points.buffer[i];
				var secondPoint = _points.buffer[i + 1];

				var hasThirdPoint = _points.length > i + 2;
				if( hasThirdPoint )
					thirdPoint = _points.buffer[i + 2];

				// we need the distance along the line of both the first and second points. distanceSoFar will always be for the furthest point
				// which is the previous point before adding the current segment distance.
				var firstPointDistance = distanceSoFar;
				distanceSoFar += secondPoint.lengthFromPreviousPoint;

				var firstPointRatio = firstPointDistance / lineLength;
				var secondPointRatio = distanceSoFar / lineLength;
				var thirdPointRatio = 0f;
				if( hasThirdPoint )
					thirdPointRatio = ( distanceSoFar + thirdPoint.lengthFromPreviousPoint ) / lineLength;

				if( _useStartEndColors )
				{
					ColorExt.lerp( ref _startColor, ref _endColor, out firstPoint.color, firstPointRatio );
					ColorExt.lerp( ref _startColor, ref _endColor, out secondPoint.color, secondPointRatio );

					if( hasThirdPoint )
						ColorExt.lerp( ref _startColor, ref _endColor, out thirdPoint.color, thirdPointRatio );
				}

				if( _useStartEndWidths )
				{
					firstPoint.width = Mathf.lerp( _startWidth, _endWidth, firstPointRatio );
					secondPoint.width = Mathf.lerp( _startWidth, _endWidth, secondPointRatio );

					if( hasThirdPoint )
						thirdPoint.width = Mathf.lerp( _startWidth, _endWidth, thirdPointRatio );
				}


				if( i == 0 )
				{
					_firstSegment.setPoints( ref firstPoint, ref secondPoint );
					_secondSegment.setPoints( ref secondPoint, ref thirdPoint );
				}
				else
				{
					Utils.swap( ref _firstSegment, ref _secondSegment );
					if( hasThirdPoint )
						_secondSegment.setPoints( ref secondPoint, ref thirdPoint );
				}

				// dont recalculate the fusedPoint for the last segment since there will be no third point to work with
				if( hasThirdPoint )
				{
					var shouldFuseBottom = Vector2Ext.isTriangleCCW( firstPoint.position, secondPoint.position, thirdPoint.position );
					_secondSegment.setFusedData( shouldFuseBottom, ref _firstSegment );
				}

				// special care needs to be take with the first segment since it has a different vert count
				if( i == 0 )
					addFirstSegment( ref _firstSegment, ref _secondSegment, ref vertIndex );
				else
					addSegment( ref _firstSegment, ref vertIndex );

				_lastSegment.cloneFrom( ref _firstSegment );
			}
		}
Esempio n. 14
0
			public void setPoints( ref SegmentPoint point, ref SegmentPoint nextPoint )
			{
				angle = 0;
				this.point = point;
				this.nextPoint = nextPoint;

				// rotate 90 degrees before calculating and cache cos/sin
				var radians = Mathf.atan2( nextPoint.position.Y - point.position.Y, nextPoint.position.X - point.position.X );
				radians += MathHelper.PiOver2;
				var halfCos = Mathf.cos( radians ) * 0.5f;
				var halfSin = Mathf.sin( radians ) * 0.5f;

				tl = point.position - new Vector2( point.width * halfCos, point.width * halfSin );
				tr = nextPoint.position - new Vector2( nextPoint.width * halfCos, nextPoint.width * halfSin );
				br = nextPoint.position + new Vector2( nextPoint.width * halfCos, nextPoint.width * halfSin );
				bl = point.position + new Vector2( point.width * halfCos, point.width * halfSin );
			}
Esempio n. 15
0
			public void cloneFrom( ref Segment segment )
			{
				tl = segment.tl;
				tr = segment.tr;
				br = segment.br;
				bl = segment.bl;
				point = segment.point;
				nextPoint = segment.nextPoint;
				hasFusedPoint = segment.hasFusedPoint;
				shouldFuseBottom = segment.shouldFuseBottom;
				angle = segment.angle;
			}
Esempio n. 16
0
        private static List <Segment> RemoveIntersections(List <Segment> segments, int coord, Segment.Type type)
        {
            List <SegmentPoint> points      = new List <SegmentPoint>();
            List <Segment>      outSegments = new List <Segment>();

            foreach (var segment in segments)
            {
                if (Segment.Horizontal(type))
                {
                    points.Add(new SegmentPoint(segment.Start.X, segment.SegmentType, SegmentPoint.PointType.Start));
                    points.Add(new SegmentPoint(segment.End.X, segment.SegmentType, SegmentPoint.PointType.End));
                }
                else
                {
                    points.Add(new SegmentPoint(segment.Start.Y, segment.SegmentType, SegmentPoint.PointType.Start));
                    points.Add(new SegmentPoint(segment.End.Y, segment.SegmentType, SegmentPoint.PointType.End));
                }
            }
            Segment.Type currentType    = points[0].SegmentType;
            var          currentPoint   = points[0];
            var          startFound     = true;
            bool         isIntersection = false;
            bool         isFirst        = true;
            int          lastAdded      = int.MinValue;
            var          sortedPoints   = points.OrderBy(x => x.Coordinates).ToList();

            for (int i = 0; i < sortedPoints.Count - 1; i++)
            {
                if (sortedPoints[i].Coordinates == sortedPoints[i + 1].Coordinates &&
                    sortedPoints[i].SegmentType == sortedPoints[i + 1].SegmentType)
                {
                    sortedPoints[i].Type     = SegmentPoint.PointType.Start;
                    sortedPoints[i + 1].Type = SegmentPoint.PointType.Start;

                    /*удаление из середины листа слишком долгая операция, сделаем точку стартовой
                     * и она не будет рассматриваться в автомате
                     */
                }
            }
            foreach (var point in sortedPoints)
            {
                if (isFirst)
                {
                    currentType  = point.SegmentType;
                    currentPoint = point;
                    startFound   = true;
                    isFirst      = false;
                    continue;
                }
                if (isIntersection)
                {
                    startFound     = true;
                    currentPoint   = point;
                    currentType    = Segment.OppositeType(point.SegmentType);
                    isIntersection = false;
                    continue;
                }
                if (!startFound && point.Type == SegmentPoint.PointType.Start)
                {
                    if (lastAdded == point.Coordinates && outSegments.Last().SegmentType == point.SegmentType)
                    {
                        var lastSegment = outSegments.Last();
                        outSegments.RemoveAt(outSegments.Count - 1);
                        startFound = true;
                        if (Segment.Horizontal(type))
                        {
                            currentPoint = new SegmentPoint(lastSegment.Start.X, point.SegmentType, SegmentPoint.PointType.Start);
                        }
                        else
                        {
                            currentPoint = new SegmentPoint(lastSegment.Start.Y, point.SegmentType, SegmentPoint.PointType.Start);
                        }
                        continue;
                    }
                    currentPoint = point;
                    startFound   = true;
                    currentType  = point.SegmentType;
                    continue;
                }
                if (startFound && point.SegmentType == currentType && point.Type == SegmentPoint.PointType.End)
                {
                    if (Segment.Horizontal(type))
                    {
                        outSegments.Add(new Segment(currentPoint.Coordinates, coord, point.Coordinates, coord, currentType));
                    }
                    else
                    {
                        outSegments.Add(new Segment(coord, currentPoint.Coordinates, coord, point.Coordinates, currentType));
                    }
                    lastAdded  = point.Coordinates;
                    startFound = false;
                    continue;
                }
                if (startFound && point.SegmentType != currentType)
                {
                    if (Segment.Horizontal(type))
                    {
                        outSegments.Add(new Segment(currentPoint.Coordinates, coord, point.Coordinates, coord, currentType));
                    }
                    else
                    {
                        outSegments.Add(new Segment(coord, currentPoint.Coordinates, coord, point.Coordinates, currentType));
                    }
                    lastAdded      = point.Coordinates;
                    startFound     = false;
                    isIntersection = true;
                    continue;
                }
            }
            return(outSegments.Where(x => x.Length > 0).ToList());
        }
Esempio n. 17
0
 // instance functions
 /// <summary>Takes an offset relative to the beginning of this track segment and returns the point on the track corresponding to this offset in an output parameter.</summary>
 /// <param name="offset">The offset relative to the beginning of this track segment. A value of zero corresponds to the beginning of this track segment, while a value of the underlying Length field corresponds to the end of this track segment.</param>
 /// <param name="point">Receives point on the track, including its position, orientation and roll.</param>
 /// <returns>The success of the operation. This operation fails if the specified offset points to a point outside of the available track.</returns>
 public bool GetPoint(double offset, out SegmentPoint point)
 {
     if (offset < 0.0) {
         /*
          * The offset is negative and thus outside the bounds of this segment.
          * We need to continue processing with the previous segment.
          * */
         if (this.Previous.Segment is PhysicalSegment) {
             PhysicalSegment previous = (PhysicalSegment)this.Previous.Segment;
             SegmentEndpoint endpoint = this.Previous.Endpoint;
             if (endpoint == SegmentEndpoint.Beginning) {
                 return GetPoint(-offset, out point);
             } else if (endpoint == SegmentEndpoint.End) {
                 return GetPoint(previous.Length + offset, out point);
             } else {
                 throw new InvalidOperationException();
             }
         } else if (this.Previous.Segment is VirtualSegment) {
             // TODO: Virtual segments can have various endpoints.
             //       Each virtual segment needs to be handled specially.
             throw new NotImplementedException();
         } else if (this.Previous.Segment == null) {
             point = SegmentPoint.Invalid;
             return false;
         } else {
             throw new InvalidOperationException();
         }
     } else if (offset > this.Length) {
         /*
          * The offset exceeds the length of this segment and is thus outside the bounds of this segment.
          * We need to continue processing with the next segment.
          * */
         if (this.Next.Segment is PhysicalSegment) {
             PhysicalSegment next = (PhysicalSegment)this.Next.Segment;
             SegmentEndpoint endpoint = this.Next.Endpoint;
             if (endpoint == SegmentEndpoint.Beginning) {
                 return GetPoint(offset - this.Length, out point);
             } else if (endpoint == SegmentEndpoint.End) {
                 return GetPoint(this.Length + next.Length - offset, out point);
             } else {
                 throw new InvalidOperationException();
             }
         } else if (this.Next.Segment is VirtualSegment) {
             // TODO: Virtual segments can have various endpoints.
             //       Each virtual segment needs to be handled specially.
             throw new NotImplementedException();
         } else if (this.Next.Segment == null) {
             point = SegmentPoint.Invalid;
             return false;
         } else {
             throw new InvalidOperationException();
         }
     } else {
         /*
          * The offset is within the bounds of this segment.
          * We can calculate the track point data now.
          * */
         if (this is StraightSegment) {
             StraightSegment straight = (StraightSegment)this;
             Math.Vector3 position = straight.Position + offset * straight.Orientation.Z;
             double rollFactor = offset / straight.Length;
             double roll = (1.0 - rollFactor) * straight.StartingRoll + rollFactor * straight.EndingRoll;
             point = new SegmentPoint(this, position, straight.Orientation, false, roll);
             return true;
         } else if (this is CurvedSegment) {
             CurvedSegment curve = (CurvedSegment)this;
             double angle = offset / curve.Radius;
             double cosineOfAngle = System.Math.Cos(angle);
             double sineOfAngle = System.Math.Sin(angle);
             double radiusX = curve.Radius * cosineOfAngle;
             double radiusZ = curve.Radius * sineOfAngle;
             Math.Vector3 position = curve.Center - radiusX * curve.Orientation.X + radiusZ * curve.Orientation.Z;
             Math.Orientation3 orientation = Math.Orientation3.RotateAroundYAxis(curve.Orientation, cosineOfAngle, sineOfAngle);
             double rollFactor = offset / curve.Length;
             double roll = (1.0 - rollFactor) * curve.StartingRoll + rollFactor * curve.EndingRoll;
             point = new SegmentPoint(this, position, orientation, false, roll);
             return true;
         } else {
             throw new InvalidOperationException();
         }
     }
 }