Esempio n. 1
0
        /// <summary>
        /// Add points for a circular fillet around a reflex corner.
        /// Adds the start and end points
        /// </summary>
        /// <param name="p">Base point of curve</param>
        /// <param name="p0">Start point of fillet curve</param>
        /// <param name="p1">Endpoint of fillet curve</param>
        /// <param name="direction">The orientation of the fillet</param>
        /// <param name="radius">The radius of the fillet</param>
        private void AddCornerFillet(Coordinate p, Coordinate p0, Coordinate p1, OrientationIndex direction, double radius)
        {
            double dx0        = p0.X - p.X;
            double dy0        = p0.Y - p.Y;
            double startAngle = Math.Atan2(dy0, dx0);
            double dx1        = p1.X - p.X;
            double dy1        = p1.Y - p.Y;
            double endAngle   = Math.Atan2(dy1, dx1);

            if (direction == OrientationIndex.Clockwise)
            {
                if (startAngle <= endAngle)
                {
                    startAngle += 2.0 * Math.PI;
                }
            }
            else
            {    // direction == COUNTERCLOCKWISE
                if (startAngle >= endAngle)
                {
                    startAngle -= 2.0 * Math.PI;
                }
            }
            _segList.AddPt(p0);
            AddDirectedFillet(p, startAngle, endAngle, direction, radius);
            _segList.AddPt(p1);
        }
Esempio n. 2
0
        /// <summary>
        /// Adds the offset points for an outside (convex) turn
        /// </summary>
        private void AddOutsideTurn(OrientationIndex orientation, bool addStartPoint)
        {
            /**
             * Heuristic: If offset endpoints are very close together,
             * just use one of them as the corner vertex.
             * This avoids problems with computing mitre corners in the case
             * where the two segments are almost parallel
             * (which is hard to compute a robust intersection for).
             */
            if (_offset0.P1.Distance(_offset1.P0) < _distance * OffsetSegmentSeparationFactor)
            {
                _segList.AddPt(_offset0.P1);
                return;
            }

            if (_bufParams.JoinStyle == JoinStyle.Mitre)
            {
                AddMitreJoin(_s1, _offset0, _offset1, _distance);
            }
            else if (_bufParams.JoinStyle == JoinStyle.Bevel)
            {
                AddBevelJoin(_offset0, _offset1);
            }
            else
            {
                // add a circular fillet connecting the endpoints of the offset segments
                if (addStartPoint)
                {
                    _segList.AddPt(_offset0.P1);
                }
                // TESTING - comment out to produce beveled joins
                AddCornerFillet(_s1, _offset0.P1, _offset1.P0, orientation, _distance);
                _segList.AddPt(_offset1.P0);
            }
        }
        ///<summary>
        /// Adds points for a circular fillet arc between two specified angles.
        ///</summary>
        ///<remarks>
        /// The start and end point for the fillet are not added - the caller must add them if required.
        ///</remarks>
        /// <param name="p">The point around which to add the fillet points</param>
        /// <param name="startAngle">The start angle (in radians)</param>
        /// <param name="endAngle">The end angle (in radians)</param>
        /// <param name="direction">Is -1 for a CW angle, 1 for a CCW angle</param>
        /// <param name="radius">The radius of the fillet</param>
        private void AddFillet(Coordinate p, double startAngle, double endAngle, OrientationIndex direction, double radius)
        {
            int directionFactor = direction == OrientationIndex.Clockwise ? -1 : 1;

            double totalAngle = Math.Abs(startAngle - endAngle);
            int    nSegs      = (int)(totalAngle / _filletAngleQuantum + 0.5);

            if (nSegs < 1)
            {
                return;               // no segments because angle is less than increment - nothing to do!
            }
            double initAngle, currAngleInc;

            // choose angle increment so that each segment has equal length
            initAngle    = 0.0;
            currAngleInc = totalAngle / nSegs;

            double     currAngle = initAngle;
            Coordinate pt        = new Coordinate();

            while (currAngle < totalAngle)
            {
                double angle = startAngle + directionFactor * currAngle;
                pt.X = p.X + radius * Math.Cos(angle);
                pt.Y = p.Y + radius * Math.Sin(angle);
                _vertexList.AddPt(pt);
                currAngle += currAngleInc;
            }
        }
        private static bool IsAllOrientationsEqual(Coordinate[] pts)
        {
            var orient = new OrientationIndex[3];

            orient[0] = Orientation.Index(pts[0], pts[1], pts[2]);
            orient[1] = Orientation.Index(pts[1], pts[2], pts[0]);
            orient[2] = Orientation.Index(pts[2], pts[0], pts[1]);
            return(orient[0] == orient[1] && orient[0] == orient[2]);
        }
    private static LogEventPropertyValue WriteCoordinateSequence(
        CoordinateSequence?sequence,
        bool multiple,
        OrientationIndex orientation = OrientationIndex.None
        )
    {
        if (sequence == null)
        {
            return(new ScalarValue(null));
        }

        var values = new List <LogEventPropertyValue>();

        if (multiple)
        {
            if ((orientation == OrientationIndex.Clockwise && Orientation.IsCCW(sequence)) ||
                (orientation == OrientationIndex.CounterClockwise && !Orientation.IsCCW(sequence)))
            {
                CoordinateSequences.Reverse(sequence);
            }
        }

        var hasZ = sequence.HasZ;

        for (var i = 0; i < sequence.Count; i++)
        {
            var value = new List <LogEventPropertyValue>(3);
            value.Add(new ScalarValue(sequence.GetX(i)));
            value.Add(new ScalarValue(sequence.GetY(i)));

            if (hasZ)
            {
                var z = sequence.GetZ(i);
                if (!double.IsNaN(z))
                {
                    value.Add(new ScalarValue(z));
                }
            }

            if (multiple)
            {
                values.Add(new SequenceValue(value));
            }
            else
            {
                values = value;
                break;
            }
        }

        return(new SequenceValue(values));
    }
        /// <summary>
        /// Simplify the input coordinate list.
        /// </summary>
        /// <remarks>
        /// If the distance tolerance is positive, concavities on the LEFT side of the line are simplified.
        /// If the supplied distance tolerance is negative, concavities on the RIGHT side of the line are simplified.
        /// </remarks>
        /// <param name="distanceTol">Simplification distance tolerance to use</param>
        /// <returns>
        /// The simplified coordinates list
        /// </returns>
        public Coordinate[] Simplify(double distanceTol)
        {
            _distanceTol = System.Math.Abs(distanceTol);
            if (distanceTol < 0)
            {
                _angleOrientation = OrientationIndex.Clockwise;
            }

            // rely on fact that boolean array is filled with false value
            _isDeleted = new byte[_inputLine.Length];

            bool isChanged;

            do
            {
                isChanged = DeleteShallowConcavities();
            } while (isChanged);

            return(CollapseLine());
        }
Esempio n. 7
0
 /// <summary>
 /// Re-orients an orientation.
 /// </summary>
 /// <param name="orientation">The orientation</param>
 /// <returns></returns>
 public static OrientationIndex ReOrient(OrientationIndex orientation)
 {
     return((OrientationIndex)(-(int)orientation));
 }
        public float EventGetOrientation64(IntPtr evt, OrientationIndex index)
        {
            // Contract.Requires<ArgumentException>(evt != IntPtr.Zero, "The pointer to the event must be set.");

            return(default(float));
        }
Esempio n. 9
0
 private static extern float event_get_orientation_64(IntPtr evt, OrientationIndex index);
Esempio n. 10
0
 protected static float GetEventOrientation(IntPtr evt, OrientationIndex index)
 {
     return(PlatformInvocation.Running32Bit
         ? event_get_orientation_32(evt, index)
         : event_get_orientation_64(evt, index));
 }
 public static extern float event_get_orientation(IntPtr evt, OrientationIndex index);
Esempio n. 12
0
 /// <inheritdoc />
 public float GetEventOrientation(IntPtr evt, OrientationIndex index)
 {
     return(PlatformInvocation.Running32Bit
         ? _myoDeviceBridge.EventGetOrientation32(evt, index)
         : _myoDeviceBridge.EventGetOrientation64(evt, index));
 }
Esempio n. 13
0
        public float EventGetOrientation64(IntPtr evt, OrientationIndex index)
        {
            Contract.Requires<ArgumentException>(evt != IntPtr.Zero, "The pointer to the event must be set.");

            return default(float);
        }
Esempio n. 14
0
 /// <inheritdoc />
 public float EventGetOrientation64(IntPtr evt, OrientationIndex index)
 {
     return(event_get_orientation_64(evt, index));
 }
        /// <summary>
        /// Adds points for a circular fillet arc
        /// between two specified angles.
        /// The start and end point for the fillet are not added -
        /// the caller must add them if required.
        /// </summary>
        /// <param name="p">The center point</param>
        /// <param name="direction">Is -1 for a <see cref="OrientationIndex.Clockwise"/> angle, 1 for a <see cref="OrientationIndex.CounterClockwise"/> angle</param>
        /// <param name="startAngle">The start angle of the fillet</param>
        /// <param name="endAngle">The end angle of the fillet</param>
        /// <param name="radius">The radius of the fillet</param>
        private void AddDirectedFillet(Coordinate p, double startAngle, double endAngle, OrientationIndex direction, double radius)
        {
            int directionFactor = direction == OrientationIndex.Clockwise ? -1 : 1;

            double totalAngle = Math.Abs(startAngle - endAngle);
            int    nSegs      = (int)(totalAngle / _filletAngleQuantum + 0.5);

            if (nSegs < 1)
            {
                return;               // no segments because angle is less than increment - nothing to do!
            }
            // choose angle increment so that each segment has equal length
            double angleInc = totalAngle / nSegs;
            var    pt       = new Coordinate();

            for (int i = 0; i < nSegs; i++)
            {
                double angle = startAngle + directionFactor * i * angleInc;
                pt.X = p.X + radius * Math.Cos(angle);
                pt.Y = p.Y + radius * Math.Sin(angle);
                _segList.AddPt(pt);
            }
        }
Esempio n. 16
0
 /// <inheritdoc />
 public float GetEventOrientation(IntPtr evt, OrientationIndex index)
 {
     return PlatformInvocation.Running32Bit
         ? _myoDeviceBridge.EventGetOrientation32(evt, index)
         : _myoDeviceBridge.EventGetOrientation64(evt, index);
 }
Esempio n. 17
0
        public float GetEventOrientation(IntPtr evt, OrientationIndex index)
        {
            Contract.Requires <ArgumentException>(evt != IntPtr.Zero, "The event handle must be set.");

            return(default(float));
        }
Esempio n. 18
0
        /// <summary>
        /// Adds the offset points for an inside (concave) turn.
        /// </summary>
        /// <param name="orientation"></param>
        /// <param name="addStartPoint"></param>
        private void AddInsideTurn(OrientationIndex orientation, bool addStartPoint)
        {
            /**
             * add intersection point of offset segments (if any)
             */
            _li.ComputeIntersection(_offset0.P0, _offset0.P1, _offset1.P0, _offset1.P1);
            if (_li.HasIntersection)
            {
                _segList.AddPt(_li.GetIntersection(0));
            }
            else
            {
                /*
                 * If no intersection is detected,
                 * it means the angle is so small and/or the offset so
                 * large that the offsets segments don't intersect.
                 * In this case we must
                 * add a "closing segment" to make sure the buffer curve is continuous,
                 * fairly smooth (e.g. no sharp reversals in direction)
                 * and tracks the buffer correctly around the corner. The curve connects
                 * the endpoints of the segment offsets to points
                 * which lie toward the centre point of the corner.
                 * The joining curve will not appear in the final buffer outline, since it
                 * is completely internal to the buffer polygon.
                 *
                 * In complex buffer cases the closing segment may cut across many other
                 * segments in the generated offset curve.  In order to improve the
                 * performance of the noding, the closing segment should be kept as short as possible.
                 * (But not too short, since that would defeat its purpose).
                 * This is the purpose of the closingSegFactor heuristic value.
                 */

                /*
                 * The intersection test above is vulnerable to robustness errors; i.e. it
                 * may be that the offsets should intersect very close to their endpoints,
                 * but aren't reported as such due to rounding. To handle this situation
                 * appropriately, we use the following test: If the offset points are very
                 * close, don't add closing segments but simply use one of the offset
                 * points
                 */
                _hasNarrowConcaveAngle = true;
                //System.out.println("NARROW ANGLE - distance = " + distance);
                if (_offset0.P1.Distance(_offset1.P0) < _distance
                    * InsideTurnVertexSnapDistanceFactor)
                {
                    _segList.AddPt(_offset0.P1);
                }
                else
                {
                    // add endpoint of this segment offset
                    _segList.AddPt(_offset0.P1);

                    /**
                     * Add "closing segment" of required length.
                     */
                    if (_closingSegLengthFactor > 0)
                    {
                        var mid0 = new Coordinate((_closingSegLengthFactor * _offset0.P1.X + _s1.X) / (_closingSegLengthFactor + 1),
                                                  (_closingSegLengthFactor * _offset0.P1.Y + _s1.Y) / (_closingSegLengthFactor + 1));
                        _segList.AddPt(mid0);
                        var mid1 = new Coordinate((_closingSegLengthFactor * _offset1.P0.X + _s1.X) / (_closingSegLengthFactor + 1),
                                                  (_closingSegLengthFactor * _offset1.P0.Y + _s1.Y) / (_closingSegLengthFactor + 1));
                        _segList.AddPt(mid1);
                    }
                    else
                    {
                        /**
                         * This branch is not expected to be used except for testing purposes.
                         * It is equivalent to the JTS 1.9 logic for closing segments
                         * (which results in very poor performance for large buffer distances)
                         */
                        _segList.AddPt(_s1);
                    }

                    //*/
                    // add start point of next segment offset
                    _segList.AddPt(_offset1.P0);
                }
            }
        }
Esempio n. 19
0
		public static extern float event_get_orientation(IntPtr evt, OrientationIndex index);
Esempio n. 20
0
        private void WriteCoordinateSequence(Utf8JsonWriter writer, CoordinateSequence sequence, JsonSerializerOptions options, bool multiple = true, OrientationIndex orientation = OrientationIndex.None)
        {
            //writer.WritePropertyName("coordinates");
            if (sequence == null)
            {
                writer.WriteNullValue();
                return;
            }

            if (multiple)
            {
                writer.WriteStartArray();
                if (orientation == OrientationIndex.Clockwise && Orientation.IsCCW(sequence) ||
                    orientation == OrientationIndex.CounterClockwise && !Orientation.IsCCW(sequence))
                {
                    CoordinateSequences.Reverse(sequence);
                }
            }

            bool hasZ = sequence.HasZ;

            for (int i = 0; i < sequence.Count; i++)
            {
                writer.WriteStartArray();
                writer.WriteNumberValue(sequence.GetX(i));
                writer.WriteNumberValue(sequence.GetY(i));

                if (hasZ)
                {
                    double z = sequence.GetZ(i);
                    if (!double.IsNaN(z))
                    {
                        writer.WriteNumberValue(sequence.GetZ(i));
                    }
                }
                writer.WriteEndArray();

                if (!multiple)
                {
                    break;
                }
            }

            if (multiple)
            {
                writer.WriteEndArray();
            }
        }