public void CanWriteMultiPoint() { Pnt3D point1 = new Pnt3D(2600001.123, 1200000.987, 432.1); Pnt3D point2 = new Pnt3D(2600002.234, 1200002.876, 321.98); IList <IPnt> multipoint = new IPnt[] { point1, point2 }; WkbGeomWriter writer = new WkbGeomWriter(); byte[] bytes = writer.WriteMultipoint(multipoint); WkbGeomReader reader = new WkbGeomReader(); List <IPnt> deserizalized = reader.ReadMultiPoint(new MemoryStream(bytes)).ToList(); Assert.AreEqual(multipoint.Count, deserizalized.Count); for (int i = 0; i < multipoint.Count; i++) { Assert.IsTrue(deserizalized[i].Equals(multipoint[i])); } }
public void CanDetermineDistancePerpendicular() { var line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(10, 10, 0)); var point = new Pnt3D(10, 0, 0); double d = line1.GetDistancePerpendicular(point); double epsilon = MathUtils.GetDoubleSignificanceEpsilon(10); double expectedDist2D = Math.Sqrt(100 + 100) / 2; Assert.AreEqual(expectedDist2D, d, epsilon); point = new Pnt3D(10, 0, 10); d = line1.GetDistancePerpendicular(point); Assert.AreEqual(Math.Sqrt(expectedDist2D * expectedDist2D + 100), d, epsilon); point = new Pnt3D(0, 0, 0); d = line1.GetDistancePerpendicular(point); Assert.AreEqual(0, d, epsilon); point = new Pnt3D(6, 6, 0); d = line1.GetDistancePerpendicular(point); Assert.AreEqual(0, d, epsilon); }
public void CanInterpolateUndefinedZsInLinestring() { var ring1 = new List <Pnt3D>(); // ring1: horizontal: ring1.Add(new Pnt3D(0, 0, 10)); ring1.Add(new Pnt3D(0, 100, 20)); ring1.Add(new Pnt3D(100, 100, double.NaN)); ring1.Add(new Pnt3D(50, 50, double.NaN)); ring1.Add(new Pnt3D(100, 0, 20 + 10 + 10 * Math.Sqrt(2))); Pnt3D testPoint1 = new Pnt3D(100, 100, double.NaN); Pnt3D testPoint2 = new Pnt3D(50, 50, double.NaN); Linestring linestring = null; for (var i = 0; i < ring1.Count; i++) { Pnt3D[] array1 = ring1.ToArray(); CollectionUtils.Rotate(array1, i); var rotatedRing = new List <Pnt3D>(array1); linestring = new Linestring(rotatedRing); bool nanStartOrEnd = double.IsNaN(linestring.StartPoint.Z) || double.IsNaN(linestring.EndPoint.Z); Assert.True(linestring.TryInterpolateUndefinedZs()); int?pt1Idx = linestring.FindPointIdx(testPoint1, true); Assert.NotNull(pt1Idx); Pnt3D foundPt1 = linestring.GetPoint3D(pt1Idx.Value); int?pt2Idx = linestring.FindPointIdx(testPoint2, true); Assert.NotNull(pt2Idx); Pnt3D foundPt2 = linestring.GetPoint3D(pt2Idx.Value); if (!nanStartOrEnd) { // incline: 10m per 100m: double testPoint1ExpectedZ = 20 + 10; Assert.AreEqual(testPoint1ExpectedZ, foundPt1.Z); testPoint1ExpectedZ += 5 * Math.Sqrt(2); Assert.AreEqual(testPoint1ExpectedZ, foundPt2.Z); } Assert.False(linestring.GetPoints().Any(p => double.IsNaN(p.Z))); } Pnt3D point = linestring[2].StartPoint; linestring.UpdatePoint(2, point.X, point.Y, double.NaN); Assert.True(linestring.TryInterpolateUndefinedZs()); Assert.False(double.IsNaN(linestring[2].StartPoint.Z)); }
public static void AddPaths([NotNull] IList <Linestring> linestringsToAdd, [NotNull] IPolyline toResult) { Func <Pnt3D, WKSPointZ> createPoint; if (GeometryUtils.IsZAware(toResult)) { createPoint = p => WKSPointZUtils.CreatePoint(p.X, p.Y, p.Z); } else { createPoint = p => WKSPointZUtils.CreatePoint(p.X, p.Y, double.NaN); } IPath pathTemplate = GeometryFactory.CreateEmptyPath(toResult); foreach (Linestring resultLinestring in linestringsToAdd) { var pathPoints = new WKSPointZ[resultLinestring.SegmentCount + 1]; var i = 0; foreach (Line3D line3D in resultLinestring) { pathPoints[i++] = createPoint(line3D.StartPoint); } Pnt3D last = resultLinestring[resultLinestring.SegmentCount - 1].EndPoint; pathPoints[i] = createPoint(last); IPath path = GeometryFactory.Clone(pathTemplate); GeometryUtils.AddWKSPointZs((IPointCollection4)path, pathPoints); ((IGeometryCollection)toResult).AddGeometry(path); } }
public static bool?AreCoplanar([NotNull] IList <Pnt3D> points, [NotNull] Plane3D plane, double tolerance, out double maxDeviationFromPlane, out string message) { message = null; if (!plane.IsDefined) { message = $"The plane is not sufficiently defined by the input points {StringUtils.Concatenate(points, ", ")}."; maxDeviationFromPlane = double.NaN; return(null); } if (MathUtils.AreEqual( 0, GeomUtils.GetArea3D(points, new Pnt3D(plane.Normal)))) { // Technically, the plane could be defined, but it is quite random message = $"The ring is degenerate without 3D area {StringUtils.Concatenate(points, ", ")}."; maxDeviationFromPlane = double.NaN; return(null); } var coplanar = true; double maxDistance = 0; Pnt3D maxDistancePoint = null; foreach (Pnt3D pnt3D in points) { double d = plane.GetDistanceSigned(pnt3D); if (!MathUtils.AreEqual(d, 0, tolerance)) { if (Math.Abs(d) > Math.Abs(maxDistance)) { maxDistance = d; maxDistancePoint = pnt3D; } coplanar = false; } } if (!coplanar) { _msg.VerboseDebug( $"Coplanarity of point {maxDistancePoint} with plane {plane} is violated: {maxDistance}m"); message = $"Coplanarity of the plane is violated by {maxDistance} at point {maxDistancePoint}"; } maxDeviationFromPlane = Math.Abs(maxDistance); return(coplanar); }
public void CanGetAngle3DInRad180() { var a = new Pnt3D(0, 0, 0); var b = new Pnt3D(100, 100, 60); var c = new Pnt3D(200, 200, 120); Assert.AreEqual(MathUtils.ToRadians(180), GeomUtils.GetAngle3DInRad(a, b, c), MathUtils.GetDoubleSignificanceEpsilon(3)); }
public Pnt3DIntersectionPoint([NotNull] Pnt3D point, [NotNull] ISpatialReference spatialReference, double otherZ, double?zDifference = null) { Point = GeometryFactory.CreatePoint(point.X, point.Y, point.Z, double.NaN, spatialReference); Point.SnapToSpatialReference(); OtherZ = otherZ; Distance = zDifference; }
public void CanReadWritePoint() { IPoint pointXy = GeometryFactory.CreatePoint(2600000, 1200000); IPoint pointXyz = GeometryFactory.CreatePoint(2600000, 1200000, 400); WkbGeometryWriter writer = new WkbGeometryWriter(); byte[] wkb2D = writer.WritePoint(pointXy); byte[] wkb3D = writer.WritePoint(pointXyz); // Compare with AO (2D only) byte[] arcObjectsWkb = GeometryUtils.ToWkb(pointXy); Assert.AreEqual(arcObjectsWkb, wkb2D); // Compare with Wkx byte[] wkx2D = ToChristianSchwarzWkb(pointXy); Assert.AreEqual(wkx2D, wkb2D); byte[] wkx3D = ToChristianSchwarzWkb(pointXyz); Assert.AreEqual(wkx3D, wkb3D); // Bonus test: Geom WkbGeomWriter geomWriter = new WkbGeomWriter(); Pnt3D pnt2D = new Pnt3D(pointXy.X, pointXy.Y, double.NaN); byte[] bytesGeom2D = geomWriter.WritePoint(pnt2D, Ordinates.Xy); Assert.AreEqual(wkb2D, bytesGeom2D); Pnt3D pnt3D = new Pnt3D(pointXyz.X, pointXyz.Y, pointXyz.Z); byte[] bytesGeom3D = geomWriter.WritePoint(pnt3D); Assert.AreEqual(wkb3D, bytesGeom3D); // NOTE: Comparison with ST_Geometry SDE.ST_AsBinary(SHAPE) using nHibernate // connection is performed in StGeometryPerimeterRepositoryTest // Read back: WkbGeometryReader reader = new WkbGeometryReader(); IPoint restored = reader.ReadPoint(new MemoryStream(wkb2D)); Assert.IsTrue(GeometryUtils.AreEqual(pointXy, restored)); restored = reader.ReadPoint(new MemoryStream(wkb3D)); Assert.IsTrue(GeometryUtils.AreEqual(pointXyz, restored)); // Geom: WkbGeomReader geomReader = new WkbGeomReader(); Assert.IsTrue(pnt2D.Equals(geomReader.ReadPoint(new MemoryStream(bytesGeom2D)))); Assert.IsTrue(pnt3D.Equals(geomReader.ReadPoint(new MemoryStream(bytesGeom3D)))); }
public void CanGetAngle3DInRad0() { var a = new Pnt3D(3333.33, 4444.44444, 5555.55555); var b = new Pnt3D(12345.6789, 9876.54321, 5678.90123); double calculated = GeomUtils.GetAngle3DInRad(a, b, a); // Problem: How should the client code know the applicable epsilon whithout knowledge of the internal algorithm? double epsilon = MathUtils.GetDoubleSignificanceEpsilon(a.X * b.X, a.Y * b.Y); Assert.AreEqual(0, calculated, epsilon); }
public void CanWritePoint() { Pnt3D point = new Pnt3D(2600001.123, 1200000.987, 432.1); WkbGeomWriter writer = new WkbGeomWriter(); byte[] bytes = writer.WritePoint(point); WkbGeomReader reader = new WkbGeomReader(); IPnt deserializedPoint = reader.ReadPoint(new MemoryStream(bytes)); Assert.IsTrue(deserializedPoint.Equals(point)); }
public void CanDetermineIntersectionPointXYOutsideLineEnds() { var line1 = new Line3D(new Pnt3D(0, 6, 0), new Pnt3D(10, 10, 0)); var line2 = new Line3D(new Pnt3D(0, 4, 0), new Pnt3D(10, 1, 0)); double line1Factor, line2Factor; Assert.False(line1.HasIntersectionPointXY(line2, 2, out line1Factor, out line2Factor)); Pnt3D pointAlong1 = line1.GetPointAlong(line1Factor, true); Assert.Less(pointAlong1.X, -2); }
public void CanDetermineIntersectionPointXY() { var line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(10, 10, 0)); var line2 = new Line3D(new Pnt3D(2, 8, 0), new Pnt3D(10, 1, 0)); double line1Factor, line2Factor; Assert.True( line1.HasIntersectionPointXY(line2, 0, out line1Factor, out line2Factor)); Assert.Greater(line1Factor, line2Factor); double epsilon = MathUtils.GetDoubleSignificanceEpsilon(10); Pnt3D pointAlong1 = line1.GetPointAlong(line1Factor, true); Pnt3D pointAlong2 = line2.GetPointAlong(line2Factor, true); Assert.True(pointAlong1.Equals(pointAlong2, epsilon)); }
public void CanGetAngle3DInRad90() { var a = new Pnt3D(0, 0, 0); var b = new Pnt3D(0, 100, 0); var c = new Pnt3D(50, 100, 0); double expected = MathUtils.ToRadians(90); double calculated = GeomUtils.GetAngle3DInRad(a, b, c); double epsilon = MathUtils.GetDoubleSignificanceEpsilon(3); Assert.AreEqual(expected, calculated, epsilon); var d = new Pnt3D(-50, 100, 0); calculated = GeomUtils.GetAngle3DInRad(a, b, d); Assert.AreEqual(expected, calculated, epsilon); }
public void CanDetermineDistanceAlong() { var line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(10, 10, 0)); var point = new Pnt3D(2, 2, 0); double d = line1.GetDistanceAlong(point); double epsilon = MathUtils.GetDoubleSignificanceEpsilon(10); double expectedDist2D = Math.Sqrt(4 + 4); Assert.AreEqual(expectedDist2D, d, epsilon); point = new Pnt3D(2, 2, 24); d = line1.GetDistancePerpendicular(point); Assert.AreEqual(24, d, epsilon); }
private static IEnumerable <Pnt3D> CreateRandomPoints(int pointCount, double x, double y, double z) { Random random = new Random(); Pnt3D result = new Pnt3D(x, y, z); const double averageLength = 1.5; for (int i = 0; i < pointCount; i++) { result = result.ClonePnt3D(); result.X += (random.NextDouble() - 0.5) * averageLength; result.Y += (random.NextDouble() - 0.5) * averageLength; result.Z = (random.NextDouble()) * averageLength; yield return(result); } }
private bool CutLineHull3D([NotNull] Pnt3D p0s, [NotNull] Pnt3D l0, [NotNull] Pnt3D p1s, [NotNull] Pnt3D l1, double r2, out double tMin, out double tMax, out NearSegment hullStartNear, out NearSegment hullEndNear) { // Equation for points X on cylinder around p1 + u * l1 with square radius = r2 // 2 2 // ((X - p1) x l1) = r2 * l1 // // with X = p0 + t * l0, tMin and tMax can be determined // hullStartNear = NearSegment.NotNear; hullEndNear = NearSegment.NotNear; if (Geom.IsParallel) // parallel { return(Parallel(p0s, l0, p1s, l1, r2, out tMin, out tMax, ref hullStartNear, ref hullEndNear)); } double l12 = l1 * l1; double r2l12 = r2 * l12; var p0_p1 = (Pnt3D)(p0s - p1s); Pnt3D p0_p1xl1 = p0_p1.VectorProduct(l1); if (SegmentUtils.SolveSqr(Geom.L0xl12, 2 * Geom.L0xl1 * p0_p1xl1, p0_p1xl1 * p0_p1xl1 - r2l12, out tMin, out tMax)) { return(Near(p0s, l0, p1s, l1, r2, l12, ref tMin, ref tMax, ref hullStartNear, ref hullEndNear)); } return(false); }
private static Linestring GetLineString( [NotNull] IEnumerable <SegmentProxy> segments) { Pnt3D previousPoint = null; var points = new List <Pnt3D>(); foreach (var segment in segments) { var start = (Pnt3D)segment.GetStart(true); var end = (Pnt3D)segment.GetEnd(true); if (!Equals(previousPoint, start)) { points.Add(start); } points.Add(end); previousPoint = end; } return(new Linestring(points)); }
public void CanGetDistanceXYPerpendicularSigned() { var line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(10, 10, 0)); var point = new Pnt3D(2, 2, 0); double distanceAlong; Assert.AreEqual(0, line1.GetDistanceXYPerpendicularSigned(point)); Assert.AreEqual( 0, line1.GetDistanceXYPerpendicularSigned(point, out distanceAlong)); Assert.AreEqual(0.2, distanceAlong); double epsilon = MathUtils.GetDoubleSignificanceEpsilon(5); // slightly on the left: point = new Pnt3D(5.0, 5.01, 17); double expectedOffset = Math.Sqrt(2) * 0.01 / 2; double expectedOffsetAlong = expectedOffset / line1.Length2D; Assert.AreEqual(expectedOffset, line1.GetDistanceXYPerpendicularSigned(point), epsilon); Assert.AreEqual(expectedOffset, line1.GetDistanceXYPerpendicularSigned( point, out distanceAlong), epsilon); Assert.AreEqual(0.5 + expectedOffsetAlong, distanceAlong, epsilon); // slightly on the right: point = new Pnt3D(5.0, 4.99, 17); Assert.AreEqual(-expectedOffset, line1.GetDistanceXYPerpendicularSigned(point), epsilon); Assert.AreEqual(-expectedOffset, line1.GetDistanceXYPerpendicularSigned( point, out distanceAlong), epsilon); Assert.AreEqual(0.5 - expectedOffsetAlong, distanceAlong, epsilon); }
public void CanWriteMultiPoint() { Pnt3D point1 = new Pnt3D(2600001.123, 1200000.987, 432.1); Pnt3D point2 = new Pnt3D(2600002.234, 1200002.876, 321.98); var multipoint = new Multipoint <IPnt>(new[] { point1, point2 }); WkbGeomWriter writer = new WkbGeomWriter(); byte[] bytes = writer.WriteMultipoint(multipoint); WkbGeomReader reader = new WkbGeomReader(); Multipoint <IPnt> deserizalized = reader.ReadMultiPoint(new MemoryStream(bytes)); Assert.AreEqual(multipoint.PointCount, deserizalized.PointCount); Assert.IsTrue(deserizalized.Equals(multipoint)); }
public void CanCreateUndefinedPlaneFromCollinearPoints() { // first and last point is identical: var points = new List <Pnt3D> { new Pnt3D(2577627.794, 1183434.723, 635.800000000003), new Pnt3D(2577627.643, 1183437.291, 635.804999999993), new Pnt3D(2577627.794, 1183434.723, 635.800000000003) }; Plane3D plane = Plane3D.FitPlane(points, isRing: false); Assert.False(plane.IsDefined); Assert.AreEqual(0, plane.LengthOfNormalSquared, plane.Epsilon); // generally collinear: points = new List <Pnt3D> { new Pnt3D(2577627.794, 1183434.723, 635.800000000003), new Pnt3D(2577629.643, 1183437.291, 635.804999999993) }; Pnt3D pnt3D = points[0] + (points[1] - points[0]) * 3.5; points.Add(pnt3D); plane = Plane3D.FitPlane(points, isRing: false); Assert.False(plane.IsDefined); Assert.AreEqual(0, plane.LengthOfNormalSquared, plane.Epsilon); points.Add(points[0]); plane = Plane3D.FitPlane(points, isRing: true); Assert.False(plane.IsDefined); Assert.AreEqual(0, plane.LengthOfNormalSquared, plane.Epsilon); }
public void CanDetermineCorrectOrientationForPseudoLinearIntersecion() { // The linear intersection can be somewhat un-intuitive if the end points are witin the tolerance to the // other line but just outside the tolerance to the other end point. Line3D line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(5, 0, 0)); Line3D line2 = new Line3D(new Pnt3D(0.011, 0, 0), new Pnt3D(-10, 10, 0)); const double tolerance = 0.01; SegmentIntersection intersection = AssertLinearIntersection(line1, line2, tolerance, true); double startAlongSource; Pnt3D sourceStart = intersection.GetLinearIntersectionStart(line1, out startAlongSource); double endAlongSource; Pnt3D sourceEnd = intersection.GetLinearIntersectionEnd(line1, out endAlongSource); line2.ReverseOrientation(); AssertLinearIntersection(line1, line2, tolerance, false); line2 = new Line3D(new Pnt3D(0.009, -0.008, 0), new Pnt3D(-10, 10, 0)); AssertLinearIntersection(line1, line2, tolerance, true); line2.ReverseOrientation(); AssertLinearIntersection(line1, line2, tolerance, false); // Really acute: line2 = new Line3D(new Pnt3D(0.03, 0.0, 0), new Pnt3D(-10, 1, 0)); AssertLinearIntersection(line1, line2, tolerance, true); line2.ReverseOrientation(); AssertLinearIntersection(line1, line2, tolerance, false); }
public TileIndex GetTileIndexAt([NotNull] Pnt3D point) { Assert.ArgumentNotNull(point, nameof(point)); return(GetTileIndexAt(point.X, point.Y)); }
public void CanGetContainsXY() { var ring1 = new List <Pnt3D>(); ring1.Add(new Pnt3D(0, 0, 10)); ring1.Add(new Pnt3D(0, 100, 20)); ring1.Add(new Pnt3D(100, 100, 10)); ring1.Add(new Pnt3D(50, 50, 10)); ring1.Add(new Pnt3D(25, 75, 10)); ring1.Add(new Pnt3D(0, 0, 10)); Linestring l = new Linestring(ring1); double tolerance = 0.001; var pointOutsideRightOfCape = new Pnt3D(70, 50, 2); Assert.IsFalse( GeomRelationUtils.AreBoundsDisjoint(l, pointOutsideRightOfCape, tolerance)); Assert.IsFalse(GeomRelationUtils.LinesContainXY(l, pointOutsideRightOfCape, tolerance)); Assert.IsFalse( GeomRelationUtils.PolycurveContainsXY(l, pointOutsideRightOfCape, tolerance)); Assert.AreEqual( false, GeomRelationUtils.AreaContainsXY(l, pointOutsideRightOfCape, tolerance)); Assert.AreEqual( false, GeomRelationUtils.AreaContainsXY(l, pointOutsideRightOfCape, tolerance, true)); var pointOutsideLeftOfCape = new Pnt3D(40, 50, 2); Assert.IsFalse( GeomRelationUtils.AreBoundsDisjoint(l, pointOutsideLeftOfCape, tolerance)); Assert.IsFalse(GeomRelationUtils.LinesContainXY(l, pointOutsideLeftOfCape, tolerance)); Assert.IsFalse( GeomRelationUtils.PolycurveContainsXY(l, pointOutsideLeftOfCape, tolerance)); Assert.AreEqual( false, GeomRelationUtils.AreaContainsXY(l, pointOutsideLeftOfCape, tolerance)); Assert.AreEqual( false, GeomRelationUtils.AreaContainsXY(l, pointOutsideLeftOfCape, tolerance, true)); var pointInside = new Pnt3D(10, 90, 123); Assert.IsFalse(GeomRelationUtils.AreBoundsDisjoint(l, pointInside, tolerance)); Assert.IsFalse(GeomRelationUtils.LinesContainXY(l, pointInside, tolerance)); Assert.IsTrue(GeomRelationUtils.PolycurveContainsXY(l, pointInside, tolerance)); Assert.AreEqual(true, GeomRelationUtils.AreaContainsXY(l, pointInside, tolerance)); Assert.AreEqual( true, GeomRelationUtils.AreaContainsXY(l, pointInside, tolerance, true)); var pointOnTopRightCorner = new Pnt3D(100, 100, 2); Assert.IsFalse( GeomRelationUtils.AreBoundsDisjoint(l, pointOnTopRightCorner, tolerance)); Assert.IsTrue(GeomRelationUtils.LinesContainXY(l, pointOnTopRightCorner, tolerance)); Assert.IsTrue( GeomRelationUtils.PolycurveContainsXY(l, pointOnTopRightCorner, tolerance)); Assert.AreEqual( null, GeomRelationUtils.AreaContainsXY(l, pointOnTopRightCorner, tolerance)); Assert.AreEqual( null, GeomRelationUtils.AreaContainsXY(l, pointOnTopRightCorner, tolerance, true)); var pointOnCape = new Pnt3D(50, 50, 321); Assert.IsFalse(GeomRelationUtils.AreBoundsDisjoint(l, pointOnCape, tolerance)); Assert.IsTrue(GeomRelationUtils.LinesContainXY(l, pointOnCape, tolerance)); Assert.IsTrue(GeomRelationUtils.PolycurveContainsXY(l, pointOnCape, tolerance)); Assert.AreEqual(null, GeomRelationUtils.AreaContainsXY(l, pointOnCape, tolerance)); Assert.AreEqual( null, GeomRelationUtils.AreaContainsXY(l, pointOnCape, tolerance, true)); var pointOnLeftEdge = new Pnt3D(0, 50, 2); Assert.IsFalse(GeomRelationUtils.AreBoundsDisjoint(l, pointOnLeftEdge, tolerance)); Assert.IsTrue(GeomRelationUtils.LinesContainXY(l, pointOnLeftEdge, tolerance)); Assert.IsTrue(GeomRelationUtils.PolycurveContainsXY(l, pointOnLeftEdge, tolerance)); Assert.AreEqual(null, GeomRelationUtils.AreaContainsXY(l, pointOnLeftEdge, tolerance)); Assert.AreEqual( null, GeomRelationUtils.AreaContainsXY(l, pointOnLeftEdge, tolerance, true)); }
public void CanCalculateOrientationVertical() { var ring = new List <Pnt3D>(); // ring1: horizontal: ring.Add(new Pnt3D(2600000, 1200000, 500)); ring.Add(new Pnt3D(2600080, 1200060, 500)); ring.Add(new Pnt3D(2600080, 1200060, 530)); ring.Add(new Pnt3D(2600040, 1200030, 540)); ring.Add(new Pnt3D(2600000, 1200000, 530)); for (var i = 0; i < ring.Count; i++) { Pnt3D[] array1 = ring.ToArray(); CollectionUtils.Rotate(array1, i); var rotatedRing = new List <Pnt3D>(array1); rotatedRing.Add((Pnt3D)rotatedRing[0].Clone()); Linestring original = new Linestring(rotatedRing); Pnt3D rightMostBottomPoint = GetRightMostBottomPoint(original); Linestring linestring = original.Clone(); Assert.True(linestring.IsClosed); Assert.True( rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring), double.Epsilon)); AssertVerticalRing(linestring); linestring.ReverseOrientation(); AssertVerticalRing(linestring); Assert.True( rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring), double.Epsilon)); // New linestring from segments linestring = new Linestring(original.Segments); Assert.True(linestring.IsClosed); Assert.True( rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring), double.Epsilon)); AssertVerticalRing(linestring); linestring.ReverseOrientation(); AssertVerticalRing(linestring); Assert.True( rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring), double.Epsilon)); // New linestring from segments (reversed) rotatedRing.Reverse(); linestring = new Linestring(rotatedRing); Assert.True(linestring.IsClosed); Assert.True( rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring), double.Epsilon)); AssertVerticalRing(linestring); linestring.ReverseOrientation(); AssertVerticalRing(linestring); Assert.True( rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring), double.Epsilon)); // reverse, back, use (referenced!) segments again: linestring.ReverseOrientation(); linestring = new Linestring(linestring.Segments); Assert.True( rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring), double.Epsilon)); Assert.True(linestring.IsClosed); AssertVerticalRing(linestring); linestring.ReverseOrientation(); AssertVerticalRing(linestring); Assert.True( rightMostBottomPoint.EqualsXY(GetRightMostBottomPoint(linestring), double.Epsilon)); } // And a version with some slight deviations ring.Add(ring[0]); ring.Insert(1, new Pnt3D(2600040.01, 1200030.01, 500)); Linestring verticalWithin1mm = new Linestring(ring); Assert.True(verticalWithin1mm.IsVerticalRing(0.01)); }
public void CanCalculateOrientation() { var ring1 = new List <Pnt3D>(); // ring1: horizontal: ring1.Add(new Pnt3D(0, 0, 9)); ring1.Add(new Pnt3D(0, 100, 9)); ring1.Add(new Pnt3D(100, 100, 9)); ring1.Add(new Pnt3D(70, 20, 9)); ring1.Add(new Pnt3D(100, 0, 9)); for (var i = 0; i < ring1.Count; i++) { Pnt3D[] array1 = ring1.ToArray(); CollectionUtils.Rotate(array1, i); var rotatedRing = new List <Pnt3D>(array1); rotatedRing.Add((Pnt3D)rotatedRing[0].Clone()); Linestring original = new Linestring(rotatedRing); Pnt3D rightMostBottomPoint = GetRightMostBottomPoint(original); Linestring linestring = original.Clone(); Assert.True(linestring.IsClosed); Assert.True( rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring))); Assert.True(linestring.ClockwiseOriented == true); linestring.ReverseOrientation(); Assert.True(linestring.ClockwiseOriented == false); Assert.True( rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring))); linestring = new Linestring(original.Segments); Assert.True(linestring.IsClosed); Assert.True( rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring))); Assert.True(linestring.ClockwiseOriented == true); linestring.ReverseOrientation(); Assert.True(linestring.ClockwiseOriented == false); Assert.True( rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring))); rotatedRing.Reverse(); linestring = new Linestring(rotatedRing); Assert.True(linestring.IsClosed); Assert.True( rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring))); Assert.True(linestring.ClockwiseOriented == false); linestring.ReverseOrientation(); Assert.True(linestring.ClockwiseOriented == true); Assert.True( rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring))); // reverse, back, use (referenced!) segments again: linestring.ReverseOrientation(); linestring = new Linestring(linestring.Segments); Assert.True( rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring))); Assert.True(linestring.IsClosed); Assert.True(linestring.ClockwiseOriented == false); linestring.ReverseOrientation(); Assert.True(linestring.ClockwiseOriented == true); Assert.True( rightMostBottomPoint.Equals(GetRightMostBottomPoint(linestring))); } }
public void CanGetPointsFromLinestring() { var startPoint = new Pnt3D(-5, -15, -25); var endPoint = new Pnt3D(10, 20, 30); var line1 = new Line3D(startPoint, endPoint); Linestring linestring = new Linestring(new List <Line3D> { line1 }); Pnt3D start = linestring.GetPoint3D(0); Assert.True(ReferenceEquals(startPoint, start)); Pnt3D end = linestring.GetPoint3D(1); Assert.True(ReferenceEquals(endPoint, end)); var list = linestring.GetPoints(0, 1).ToList(); Assert.AreEqual(1, list.Count); Assert.True(ReferenceEquals(startPoint, list[0])); list = linestring.GetPoints(1, 1).ToList(); Assert.AreEqual(1, list.Count); Assert.True(ReferenceEquals(endPoint, list[0])); list = linestring.GetPoints(0, 2).ToList(); Assert.AreEqual(2, list.Count); Assert.True(ReferenceEquals(startPoint, list[0])); Assert.True(ReferenceEquals(endPoint, list[1])); // The same using default values list = linestring.GetPoints().ToList(); Assert.AreEqual(2, list.Count); Assert.True(Equals(startPoint, list[0])); Assert.True(Equals(endPoint, list[1])); // The same with clone list = linestring.GetPoints(0, null, true).ToList(); Assert.AreEqual(2, list.Count); Assert.False(ReferenceEquals(startPoint, list[0])); Assert.True(startPoint.Equals(list[0])); Assert.False(ReferenceEquals(endPoint, list[1])); Assert.True(endPoint.Equals(list[1])); var intermediatePoint = new Pnt3D(0, 0, 0); linestring = new Linestring(new[] { startPoint, intermediatePoint, endPoint }); start = linestring.GetPoint3D(0); Assert.True(ReferenceEquals(startPoint, start)); end = linestring.GetPoint3D(2); Assert.True(ReferenceEquals(endPoint, end)); list = linestring.GetPoints(0, 1).ToList(); Assert.AreEqual(1, list.Count); Assert.True(ReferenceEquals(startPoint, list[0])); list = linestring.GetPoints(2, 1).ToList(); Assert.AreEqual(1, list.Count); Assert.True(ReferenceEquals(endPoint, list[0])); list = linestring.GetPoints(0, 2).ToList(); Assert.AreEqual(2, list.Count); Assert.True(ReferenceEquals(startPoint, list[0])); Assert.True(ReferenceEquals(intermediatePoint, list[1])); list = linestring.GetPoints().ToList(); Assert.AreEqual(3, list.Count); Assert.True(ReferenceEquals(startPoint, list[0])); Assert.True(ReferenceEquals(intermediatePoint, list[1])); Assert.True(ReferenceEquals(endPoint, list[2])); }
public static List <WKSPointZ> ProjectToPlane([NotNull] Plane plane, [NotNull] IEnumerable <Pnt> points) { if (plane.IsDefined) { WKSPointZ planeVector1; WKSPointZ planeVector2; // orthogonal to planeVector1 plane.GetPlaneVectors(out planeVector1, out planeVector2); var projectedPoints = new List <WKSPointZ>(); foreach (Pnt point in points) { var projected = new WKSPointZ { X = planeVector1.X * point.X + planeVector1.Y * point.Y + planeVector1.Z * point[2], Y = planeVector2.X * point.X + planeVector2.Y * point.Y + planeVector2.Z * point[2] }; projectedPoints.Add(projected); } return(projectedPoints); } // the plane is not defined var linears = new List <WKSPointZ>(); Pnt start = null; Pnt direction = null; foreach (Pnt point in points) { if (start == null) { start = point; } double dx = point.X - start.X; double dy = point.Y - start.Y; double dz = point[2] - start[2]; double l = Math.Sqrt(dx * dx + dy * dy + dz * dz); if (Math.Abs(l) > double.Epsilon) { if (direction == null) { direction = new Pnt3D(dx, dy, dz); } else { l = l * Math.Sign(direction.X * dx + direction.Y * dy + direction[2] * dz); } } var linear = new WKSPointZ { X = l }; linears.Add(linear); } return(linears); }
public void CanCutAlongUsingZSources() { GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature); GeometryUtils.MakeZAware(sourceFeature.Shape); GeometryUtils.MakeZAware(targetFeature.Shape); var normal = new Vector(new[] { 0.5, 0.5, 2 }); Pnt3D planePoint = new Pnt3D(2600000, 1200000, 600); Plane3D sourcePlane = new Plane3D(normal, planePoint); ChangeAlongZUtils.AssignZ((IPointCollection)sourceFeature.Shape, sourcePlane); GeometryUtils.ApplyConstantZ(targetFeature.Shape, 500); CalculateCutLinesRequest calculationRequest = CreateCalculateCutLinesRequest(sourceFeature, targetFeature); CalculateCutLinesResponse calculateResponse = ChangeAlongServiceUtils.CalculateCutLines(calculationRequest, null); Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape, (ReshapeAlongCurveUsability)calculateResponse.ReshapeLinesUsability); AssertReshapeLineCount(calculateResponse.CutLines, 1, 1); IPolyline reshapeLine = (IPolyline)ProtobufGeometryUtils.FromShapeMsg(calculateResponse.CutLines[0].Path); Assert.NotNull(reshapeLine); Assert.AreEqual(1000, (reshapeLine).Length); Linestring cutLinestring = GeometryConversionUtils.GetLinestring(GeometryUtils.GetPaths(reshapeLine).Single()); Pnt3D midPoint = (Pnt3D)cutLinestring.GetPointAlong(0.5, true); List <Pnt3D> points = GeometryConversionUtils.GetPntList(reshapeLine); Assert.IsTrue(points.All(p => MathUtils.AreEqual(p.Z, 500.0))); // // Cutting - TargetZ // var applyRequest = new ApplyCutLinesRequest(); applyRequest.CutLines.Add(calculateResponse.CutLines[0]); applyRequest.CalculationRequest = calculationRequest; applyRequest.InsertVerticesInTarget = false; applyRequest.ChangedVerticesZSource = (int)ChangeAlongZSource.Target; ApplyCutLinesResponse applyResponse = ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null); Assert.AreEqual(2, applyResponse.ResultFeatures.Count); List <IGeometry> cutGeometries = applyResponse.ResultFeatures.Select(GetShape).ToList(); Assert.AreEqual(1000 * 1000, cutGeometries.Sum(g => ((IArea)g).Area)); List <MultiPolycurve> multiPolycurves = cutGeometries .Select(g => GeometryConversionUtils.CreateMultiPolycurve((IPolycurve)g)) .ToList(); foreach (MultiPolycurve multiPolycurve in multiPolycurves) { Line3D segment = multiPolycurve.FindSegments(midPoint, 0.001).First().Value; Assert.AreEqual(500, segment.StartPoint.Z); Assert.AreEqual(500, segment.EndPoint.Z); } // // Cutting - Interpolate // applyRequest = new ApplyCutLinesRequest(); applyRequest.CutLines.Add(calculateResponse.CutLines[0]); applyRequest.CalculationRequest = calculationRequest; applyRequest.InsertVerticesInTarget = false; applyRequest.ChangedVerticesZSource = (int)ChangeAlongZSource.InterpolatedSource; applyResponse = ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null); Assert.AreEqual(2, applyResponse.ResultFeatures.Count); cutGeometries = applyResponse.ResultFeatures.Select(GetShape).ToList(); Assert.AreEqual(1000 * 1000, cutGeometries.Sum(g => ((IArea)g).Area)); multiPolycurves = cutGeometries .Select(g => GeometryConversionUtils.CreateMultiPolycurve((IPolycurve)g)) .ToList(); foreach (MultiPolycurve multiPolycurve in multiPolycurves) { List <Line3D> segments = multiPolycurve.FindSegments(midPoint, 0.001) .Select(kvp => kvp.Value).ToList(); Assert.AreEqual(2, segments.Count); // Check if they are properly ordered and same length Assert.AreEqual(segments[0].EndPoint, segments[1].StartPoint); Assert.AreEqual(segments[0].Length2D, segments[1].Length2D); // Check if they are interpolated double average = (segments[0].StartPoint.Z + segments[1].EndPoint.Z) / 2; Assert.AreEqual(average, segments[0].EndPoint.Z); } // // Cutting - Plane // applyRequest = new ApplyCutLinesRequest(); applyRequest.CutLines.Add(calculateResponse.CutLines[0]); applyRequest.CalculationRequest = calculationRequest; applyRequest.InsertVerticesInTarget = false; applyRequest.ChangedVerticesZSource = (int)ChangeAlongZSource.SourcePlane; applyResponse = ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null); Assert.AreEqual(2, applyResponse.ResultFeatures.Count); cutGeometries = applyResponse.ResultFeatures.Select(GetShape).ToList(); Assert.AreEqual(1000 * 1000, cutGeometries.Sum(g => ((IArea)g).Area)); multiPolycurves = cutGeometries .Select(g => GeometryConversionUtils.CreateMultiPolycurve((IPolycurve)g)) .ToList(); foreach (MultiPolycurve multiPolycurve in multiPolycurves) { bool?coplanar = ChangeAlongZUtils.AreCoplanar( multiPolycurve.GetPoints().ToList(), sourcePlane, 0.01, out double _, out string _); Assert.IsTrue(coplanar); } }