Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
            private int InitPlaneOffsets(bool reportErrors,
                                         [CanBeNull] IFeature involvedFeature)
            {
                const int noError = 0;

                if (_minOffset <= 0 && _maxOffset >= 0)
                {
                    return(noError);
                }

                Plane3D plane      = Plane;
                var     unitNormal = UnitNormal;

                // double nf = plane.Nf;

                _minOffset = 0;
                _maxOffset = 0;
                var segmentsCount = 0;

                foreach (SegmentProxy segment in SegmentsPlane.Segments)
                {
                    segmentsCount++;
                    IPnt point = segment.GetStart(true);
                    // double f = normal.X * point.X + normal.Y * point.Y + normal.Z * point[2] + nf;
                    double distanceSigned =
                        plane.GetDistanceSigned(point.X, point.Y, point[2]);
                    double offset = Math.Abs(distanceSigned);

                    if (distanceSigned > 0 == unitNormal[2] > 0
                        )                 // oriented same as normal
                    {
                        _maxOffset = Math.Max(offset, _maxOffset);
                    }
                    else
                    {
                        _minOffset = Math.Min(-offset, _minOffset);
                    }
                }

                var coplanarityTolerance = GeomUtils.AdjustCoplanarityTolerance(
                    plane, _parent.CoplanarityTolerance,
                    _parent._zSrTolerance, _parent._xySrTolerance);

                double maxOffset = Math.Max(Math.Abs(_maxOffset), Math.Abs(_minOffset));

                _coplanar = maxOffset < coplanarityTolerance;

                if (_coplanar || !reportErrors || involvedFeature == null)
                {
                    return(noError);
                }

                IMultiPatch errorGeometry =
                    SegmentUtils.CreateMultiPatch(SegmentsPlane.Segments);

                return(_parent.ReportNonCoplanarFace(segmentsCount, maxOffset,
                                                     errorGeometry, involvedFeature));
            }