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)); }
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); } }
/** * 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 }
/// <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)); } }
/*! * 功能 普通线声源分割 * 参数 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); }
/// <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); }