public static Plane3D CreatePlane3D([NotNull] IEnumerable <SegmentProxy> ringSegments) { return(Plane3D.FitPlane( GetPoints(ringSegments, false) .Select(p => new Pnt3D(p.X, p.Y, p[2])) .ToList(), true)); }
public void CanKeepEpsilonAtReasonableLevel() { var result = new List <Pnt3D>(); // points spaced by a few 100m result.Add(new Pnt3D { X = 2723729.625, Y = 1251631.61625, Z = 601.388749999984 }); result.Add(new Pnt3D { X = 2723531.44625, Y = 1251727.94, Z = 615.443749999991 }); result.Add(new Pnt3D { X = 2723633.2675, Y = 1251824.26375, Z = 661.388749999984 }); result.Add(result[0]); Plane3D plane1 = Plane3D.FitPlane(result, true); result.Reverse(); Plane3D plane2 = Plane3D.FitPlane(result, true); Assert.Less(plane1.Epsilon, 0.5); Assert.True(plane1.IsParallel(plane2)); // opposite directon normal: Assert.False(plane1.Equals(plane2)); Assert.True(plane1.IsCoincident(plane2)); }
public void CanGetDistanceToVerticalPlane3D() { List <Pnt3D> points = GetVerticalTrianglePoints(); Plane3D plane = Plane3D.FitPlane(points); Console.WriteLine(@"A: " + plane.A); Console.WriteLine(@"B: " + plane.B); Console.WriteLine(@"C: " + plane.C); Console.WriteLine(@"D: " + plane.D); Assert.AreEqual(0, plane.C, plane.Epsilon); // vertical Assert.AreEqual(1, plane.GetUnitNormal().LengthSquared); Assert.AreEqual(0.89606641473951276, plane.GetUnitNormal().X, plane.Epsilon); Assert.AreEqual(0.44392001574143475, plane.GetUnitNormal().Y, plane.Epsilon); foreach (Pnt3D point in points) { double distance = plane.GetDistanceAbs(point.X, point.Y, point.Z); Console.WriteLine(@"{0}: {1}", point, distance); Assert.AreEqual(0, distance, plane.Epsilon); } Assert.Catch <InvalidOperationException>(() => plane.GetZ(100, 100)); }
public void CanDetermineInclinedPlaneCoincidenceMirroredAt0() { var result = new List <Pnt3D>(); result.Add(new Pnt3D { X = 2723729.625, Y = 1251631.61625, Z = 601.388749999984 }); result.Add(new Pnt3D { X = 2723531.44625, Y = 1251727.94, Z = 615.443749999991 }); result.Add(new Pnt3D { X = 2723633.2675, Y = 1251824.26375, Z = 661.388749999984 }); result.Add(result[0]); Plane3D plane1 = Plane3D.FitPlane(result, true); for (var i = 0; i < result.Count; i++) { result[i] = result[i] * -1; } result.Reverse(); Plane3D plane2 = Plane3D.FitPlane(result, true); Assert.False(plane1.Equals(plane2)); Assert.True(plane1.IsParallel(plane2)); Assert.False(plane1.IsCoincident(plane2)); }
public void CanGetZOfNearlyHorizontalPlane3D() { var points = new List <Pnt3D>(); points.Add(new Pnt3D { X = 2723729.625, Y = 1251631.61625, Z = 601 }); points.Add(new Pnt3D { X = 2723531.44625, Y = 1251727.94, Z = 601 }); points.Add(new Pnt3D { X = 2723633.2675, Y = 1251824.26375, Z = 601 }); points[0].Z += 0.001; points.Add(points[0]); Plane3D plane = Plane3D.FitPlane(points, true); foreach (Pnt3D point in points) { double z = plane.GetZ(point.X, point.Y); Console.WriteLine(@"{0}: {1}", point, z); Assert.AreEqual(point.Z, z, plane.Epsilon); } const double farAwayX = -1000000.12345; const double farAwayY = -1000000.6789; double z0 = plane.GetZ(farAwayX, farAwayY); Assert.AreEqual(0, plane.GetDistanceSigned(farAwayX, farAwayY, z0), plane.Epsilon); }
public static bool?AreCoplanar([NotNull] IList <Pnt3D> points, double tolerance, out double maxDeviationFromPlane, out string message) { Assert.ArgumentCondition(points.Count > 0, "No points provided"); Plane3D plane = Plane3D.FitPlane(points, true); return(AreCoplanar(points, plane, tolerance, out maxDeviationFromPlane, out message)); }
private static Plane3D FitPlane3D(double[] x, double[] y, double[] z, bool isRing = false) { var points = new List <Pnt3D>(); for (var i = 0; i < x.Length; i++) { points.Add(new Pnt3D(x[i], y[i], z[i])); } Plane3D plane = Plane3D.FitPlane(points, isRing); return(plane); }
public void CanGetDistanceToNearlyVerticalPlane3D() { List <Pnt3D> points = GetVerticalTrianglePoints(); points[0].Y += 0.01; Plane3D plane = Plane3D.FitPlane(points); foreach (Pnt3D point in points) { double distance = plane.GetDistanceAbs(point.X, point.Y, point.Z); Console.WriteLine(@"{0}: {1}", point, distance); Assert.AreEqual(0, distance, plane.Epsilon); } double definedZ = plane.GetZ(100, 100); Assert.AreEqual(0, plane.GetDistanceAbs(100, 100, definedZ), plane.Epsilon); }
public void CanDeterminePlaneCoincidence() { var x = new double[] { 0, 0, 1, 1, 0 }; var y = new double[] { 0, 1, 1, 0, 0 }; var z = new double[] { 0, 10, 10, 0, 0 }; Plane3D plane1 = FitPlane3D(x, y, z, true); var points2 = new List <Pnt3D>(); points2.Add(new Pnt3D(234, 567, plane1.GetZ(234, 567))); points2.Add(new Pnt3D(987, 654, plane1.GetZ(987, 654))); points2.Add(new Pnt3D(-432, 881, plane1.GetZ(432, 881))); Plane3D plane2 = Plane3D.FitPlane(points2); Assert.False(plane1.Equals(plane2)); Assert.True(plane1.IsCoincident(plane2)); }
public void CanCreatePlane3DFrom3Points() { var points = new List <Pnt3D> { new Pnt3D(2577627.794, 1183434.723, 635.800000000003), new Pnt3D(2577627.643, 1183437.291, 635.804999999993), new Pnt3D(2577629.794, 1183438.723, 635.800000000003) }; Plane3D plane = Plane3D.FitPlane(points, isRing: false); Assert.True(plane.IsDefined); Assert.False(MathUtils.AreEqual(0, plane.LengthOfNormalSquared, plane.Epsilon)); points.Add(points[0]); plane = Plane3D.FitPlane(points, isRing: true); Assert.True(plane.IsDefined); Assert.False(MathUtils.AreEqual(0, plane.LengthOfNormalSquared, plane.Epsilon)); }
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 CanCutPolygonWithZSourcePlane() { ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95); IPolygon originalPoly = GeometryFactory.CreatePolygon( GeometryFactory.CreateEnvelope(2600000, 1200000, 500, 100, 100, lv95)); IPolygon innerRingPoly = GeometryFactory.CreatePolygon( GeometryFactory.CreateEnvelope(2600000, 1200000, 500, 10, 10, lv95)); Plane3D plane = Plane3D.FitPlane(new List <Pnt3D> { new Pnt3D(2600000, 1200000, 500), new Pnt3D(2600100, 1200100, 580), new Pnt3D(2600000, 1200100, 550) }); ((IGeometryCollection)originalPoly).AddGeometryCollection( (IGeometryCollection)innerRingPoly); GeometryUtils.Simplify(originalPoly); ChangeAlongZUtils.AssignZ((IPointCollection)originalPoly, plane); // The non-z-aware cut line cuts north of the inner ring -> the inner ring should be assigned to the southern result IPolyline cutLine = GeometryFactory.CreateLine( GeometryFactory.CreatePoint(2600000 - 100, 1200020), GeometryFactory.CreatePoint(2600000 - 40, 1200020), GeometryFactory.CreatePoint(2600000 - 40, 1200040), GeometryFactory.CreatePoint(2600000 + 40, 1200040), GeometryFactory.CreatePoint(2600000 + 40, 1200020), GeometryFactory.CreatePoint(2600000 + 100, 1200020)); cutLine.SpatialReference = lv95; bool customIntersectOrig = IntersectionUtils.UseCustomIntersect; try { IntersectionUtils.UseCustomIntersect = false; const ChangeAlongZSource zSource = ChangeAlongZSource.SourcePlane; var resultsAo = CutGeometryUtils.TryCut(originalPoly, cutLine, zSource); IntersectionUtils.UseCustomIntersect = true; var resultsGeom = CutGeometryUtils.TryCut(originalPoly, cutLine, zSource); Assert.NotNull(resultsAo); Assert.NotNull(resultsGeom); EnsureCutResult(resultsAo, originalPoly, plane, 3); EnsureCutResult(resultsGeom, originalPoly, plane, 3); // NOTE: The results have different start/end points, therefore GeometryUtils.AreEqual is false Assert.True(GeometryUtils.AreEqualInXY(resultsAo[0], resultsGeom[0])); Assert.True(GeometryUtils.AreEqualInXY(resultsAo[1], resultsGeom[1])); Assert.AreEqual(0, IntersectionUtils.GetZOnlyDifferenceLines( (IPolycurve)resultsAo[0], (IPolycurve)resultsGeom[0], 0.001) .Length); Assert.AreEqual(0, IntersectionUtils.GetZOnlyDifferenceLines( (IPolycurve)resultsAo[1], (IPolycurve)resultsGeom[1], 0.001) .Length); } finally { IntersectionUtils.UseCustomIntersect = customIntersectOrig; } }