public static Geometry PointFieldStar(Geometry ptsGeom, Geometry centrePt)
        {
            var pts    = ptsGeom.Coordinates;
            var centre = centrePt.Coordinate;

            var orderedPts = new List <OrderedPoint>();

            foreach (var p in pts)
            {
                double ang = AngleUtility.Angle(centre, p);
                orderedPts.Add(new OrderedPoint(p, ang));
            }

            orderedPts.Sort();
            int n    = pts.Length + 1;
            var ring = new Coordinate[n];
            int i    = 0;

            foreach (var op in orderedPts)
            {
                ring[i++] = op.Point;
            }
            // close ring
            ring[n - 1] = ring[0].Copy();
            return(ptsGeom.Factory.CreatePolygon(ring));
        }
示例#2
0
        private double GetAngleDifference(Coordinate coordinate1, Coordinate coordinate2, Coordinate coordinate3)
        {
            var angle1 = AngleUtility.ToDegrees(AngleUtility.Angle(coordinate1, coordinate2));
            var angle2 = AngleUtility.ToDegrees(AngleUtility.Angle(coordinate2, coordinate3));

            return(Math.Abs(angle2 - angle1));
        }
 public void TestAngle()
 {
     Assert.AreEqual(AngleUtility.Angle(new Coordinate(10, 0)), 0.0, Tolerance);
     Assert.AreEqual(AngleUtility.Angle(new Coordinate(10, 10)), Math.PI / 4, Tolerance);
     Assert.AreEqual(AngleUtility.Angle(new Coordinate(0, 10)), Math.PI / 2, Tolerance);
     Assert.AreEqual(AngleUtility.Angle(new Coordinate(-10, 10)), 0.75 * Math.PI, Tolerance);
     Assert.AreEqual(AngleUtility.Angle(new Coordinate(-10, 0)), Math.PI, Tolerance);
     Assert.AreEqual(AngleUtility.Angle(new Coordinate(-10, -0.1)), -3.131592986903128, Tolerance);
     Assert.AreEqual(AngleUtility.Angle(new Coordinate(-10, -10)), -0.75 * Math.PI, Tolerance);
 }
        public void angle_utility_handles_orientation()
        {
            LineString lineString1 = new LineString(new[] { new Coordinate(1, 1), new Coordinate(2, 2) });
            LineString lineString2 = new LineString(new[] { new Coordinate(2, 2), new Coordinate(1, 1) });
            double     angle1      = AngleUtility.ToDegrees(
                AngleUtility.Angle(lineString1.StartPoint.Coordinate, lineString1.EndPoint.Coordinate));
            double angle2 = AngleUtility.ToDegrees(
                AngleUtility.Angle(lineString2.StartPoint.Coordinate, lineString2.EndPoint.Coordinate));

            Assert.AreEqual(45d, angle1);
            Assert.AreEqual(-135d, angle2);
        }
        ///<summary>
        /// Adds a limited mitre join connecting the two reflex offset segments.
        ///</summary>
        /// <remarks>
        /// A limited mitre is a mitre which is beveled at the distance
        /// determined by the mitre ratio limit.
        /// </remarks>
        /// <param name="offset0">The first offset segment</param>
        /// <param name="offset1">The second offset segment</param>
        /// <param name="distance">The offset distance</param>
        /// <param name="mitreLimit">The mitre limit ratio</param>
        private void AddLimitedMitreJoin(
            LineSegment offset0,
            LineSegment offset1,
            double distance,
            double mitreLimit)
        {
            Coordinate basePt = _seg0.P1;

            double ang0 = AngleUtility.Angle(basePt, _seg0.P0);
            double ang1 = AngleUtility.Angle(basePt, _seg1.P1);

            // oriented angle between segments
            double angDiff = AngleUtility.AngleBetweenOriented(_seg0.P0, basePt, _seg1.P1);
            // half of the interior angle
            double angDiffHalf = angDiff / 2;

            // angle for bisector of the interior angle between the segments
            double midAng = AngleUtility.Normalize(ang0 + angDiffHalf);
            // rotating this by PI gives the bisector of the reflex angle
            double mitreMidAng = AngleUtility.Normalize(midAng + Math.PI);

            // the miterLimit determines the distance to the mitre bevel
            double mitreDist = mitreLimit * distance;
            // the bevel delta is the difference between the buffer distance
            // and half of the length of the bevel segment
            double bevelDelta   = mitreDist * Math.Abs(Math.Sin(angDiffHalf));
            double bevelHalfLen = distance - bevelDelta;

            // compute the midpoint of the bevel segment
            double     bevelMidX  = basePt.X + mitreDist * Math.Cos(mitreMidAng);
            double     bevelMidY  = basePt.Y + mitreDist * Math.Sin(mitreMidAng);
            Coordinate bevelMidPt = new Coordinate(bevelMidX, bevelMidY);

            // compute the mitre midline segment from the corner point to the bevel segment midpoint
            LineSegment mitreMidLine = new LineSegment(basePt, bevelMidPt);

            // finally the bevel segment endpoints are computed as offsets from
            // the mitre midline
            Coordinate bevelEndLeft  = mitreMidLine.PointAlongOffset(1.0, bevelHalfLen);
            Coordinate bevelEndRight = mitreMidLine.PointAlongOffset(1.0, -bevelHalfLen);

            if (_side == Positions.Left)
            {
                _vertexList.AddPt(bevelEndLeft);
                _vertexList.AddPt(bevelEndRight);
            }
            else
            {
                _vertexList.AddPt(bevelEndRight);
                _vertexList.AddPt(bevelEndLeft);
            }
        }
示例#6
0
        /**
         * erzeugt einen Punkt p, wo
         * die Linie zwischen <code>anchor</code> und p
         * die Länge <code>length</code> hat und
         * quer zur Linie zwischen <code>anchor</code> und <code>coordinate</code> ist
         * @param gf
         * @param anchor
         * @param coordinate
         * @param direction wenn true: der Winkel ist 270° (rechts), sonst 90° (links)
         * @param length
         * @return
         */
        public static Coordinate createRectangle(Coordinate anchor, Coordinate coordinate, bool direction, double length)
        {
            if (coordinate.Equals2D(anchor))
            {
                return(null);
            }

            Coordinate coordShift = shift(coordinate, new Coordinate(-anchor.X, -anchor.Y));             // verschieben
            double     angle      = AngleUtility.Angle(coordShift) + (direction ? -1 : 1) * Math.PI / 2; // Winkel links oder rechts um 90° drehen
            Coordinate coord      = new Coordinate(length * Math.Cos(angle), length * Math.Sin(angle));

            return(shift(coord, anchor));  // zurückverschieben
        }
示例#7
0
        /// <summary>
        /// Adds a semi-circular cap CCW around the point <paramref name="p"/>.
        /// </summary>
        /// <param name="p">The centre point of the cap</param>
        /// <param name="r">The cap radius</param>
        /// <param name="t1">the starting point of the cap</param>
        /// <param name="t2">The ending point of the cap</param>
        /// <param name="coords">The coordinate list to add to</param>
        private void AddCap(Coordinate p, double r, Coordinate t1, Coordinate t2, CoordinateList coords)
        {
            double angStart = AngleUtility.Angle(p, t1);
            double angEnd   = AngleUtility.Angle(p, t2);

            if (angStart < angEnd)
            {
                angStart += 2 * Math.PI;
            }

            int indexStart = CapAngleIndex(angStart);
            int indexEnd   = CapAngleIndex(angEnd);

            for (int i = indexStart; i > indexEnd; i--)
            {
                // use negative increment to create points CW
                double ang = CapAngle(i);
                coords.Add(ProjectPolar(p, r, ang));
            }
        }
示例#8
0
        /*!
         * 功能 普通线声源分割
         * 参数 splitLength分割因子 line 需要分割的生源线
         * 返回值 分割后的声源线集合
         * 版本号 1.0
         * 作者 樊晓剑
         * 创建时间  2016年4月27日
         * 修改时间
         */

        public Queue <Geometry> staticPartition(double splitLength, Geometry line)
        {
            //构建返回值集合
            Queue <Geometry> lineSource = new Queue <Geometry>();

            //如果声源线长度小于分割长度,返回其本身
            if (line.Length() <= splitLength)
            {
                lineSource.Enqueue(line);
            }
            else
            {
                double[]   before = new double[3];
                double[]   after  = new double[3];
                Coordinate conBefore;
                Coordinate conAfter;
                Geometry   sourceline;
                for (int i = 0; i < line.GetPointCount() - 1; i++)
                {
                    line.GetPoint(i, before);
                    line.GetPoint(i + 1, after);

                    conBefore = new Coordinate(before[0], before[1]);
                    conAfter  = new Coordinate(after[0], after[1]);
                    while (conAfter.Distance(conBefore) > splitLength)
                    {
                        // double angle = AngleUtility.AngleBetween(pointCoordinates[i + 1], pointCoordinate, new Coordinate(pointCoordinates[i + 1].X, pointCoordinate.Y));// 计算两点与水平线夹角
                        double angle = AngleUtility.Angle(conBefore, conAfter);                                                        // 计算两点与水平线夹角
                        double xplus = conBefore.X + splitLength * Math.Cos(angle);                                                    // 计算分割点坐标
                        double yplus = conBefore.Y + splitLength * Math.Sin(angle);
                        lineSource.Enqueue(GeometryCreate.createLineString3D(conBefore.X, conBefore.Y, conBefore.Z, xplus, yplus, 0)); // 添加分割线段
                        // 将分割点设为新的起点
                        conBefore.X = xplus;
                        conBefore.Y = yplus;
                        // break;
                    }
                    lineSource.Enqueue(GeometryCreate.createLineString3D(conBefore.X, conBefore.Y, conBefore.Z, conAfter.X, conAfter.Y, conAfter.Z));
                }
            }
            return(lineSource);
        }
示例#9
0
        /// <summary>
        /// Rotates the label for the given feature by the angle of the LabelSymbolizer.
        /// </summary>
        /// <param name="symb">LabelSymbolizer that indicates the angle to use.</param>
        /// <param name="feature">Feature whose label gets rotated.</param>
        /// <param name="lineString">Line string to get the angle from if line orientation should be used.</param>
        /// <returns>Resulting angle in degree.</returns>
        private static float GetAngleToRotate(ILabelSymbolizer symb, IFeature feature, Geometry lineString = null)
        {
            if (symb.UseAngle)
            {
                return(ToSingle(symb.Angle));
            }

            if (symb.UseLabelAngleField)
            {
                var angleField = symb.LabelAngleField;
                if (string.IsNullOrEmpty(angleField))
                {
                    return(0);
                }
                return(ToSingle(feature.DataRow[angleField]));
            }

            if (symb.UseLineOrientation)
            {
                LineString ls = lineString as LineString;
                if (ls != null)
                {
                    ls = GetSegment(ls, symb);
                    if (ls == null)
                    {
                        return(0);
                    }
                    if (symb.LineOrientation == LineOrientation.Parallel)
                    {
                        return(ToSingle(-AngleUtility.Angle(ls.StartPoint.Coordinate, ls.EndPoint.Coordinate)));
                    }
                    return(ToSingle(-AngleUtility.Angle(ls.StartPoint.Coordinate, ls.EndPoint.Coordinate) - 90));
                }
            }

            return(0);
        }