コード例 #1
0
 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));
 }
コード例 #2
0
        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));
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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));
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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));
        }
コード例 #10
0
        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));
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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;
            }
        }