示例#1
0
        // Returns true of the points p0 is on the closed line formed by p1 and p2
        // returns false if p0 equals p1 or p2
        private bool PointIsOnLine(MWPoint3D p1, MWPoint3D p2, MWPoint3D p0)
        {
            double tol = 1e-5;

            if (Math.Abs(p0.X - p1.X) < tol && Math.Abs(p0.Y - p1.Y) < tol && Math.Abs(p0.Z - p1.Z) < tol)
            {
                return(false);
            }
            if (Math.Abs(p0.X - p2.X) < tol && Math.Abs(p0.Y - p2.Y) < tol && Math.Abs(p0.Z - p2.Z) < tol)
            {
                return(false);
            }
            MWVector3D v1      = new MWVector3D(p0.X - p1.X, p0.Y - p1.Y, p0.Z - p1.Z);
            MWVector3D v2      = new MWVector3D(p0.X - p2.X, p0.Y - p2.Y, p0.Z - p2.Z);
            MWVector3D vp      = Vectors3D.VectorialProduct(v1, v2);
            bool       aligned = Math.Sqrt(vp.X * vp.X + vp.Y * vp.Y + vp.Z * vp.Z) < 1e-4;

            if (aligned)
            {
                return(Points.Distance3D(p0, p1) + Points.Distance3D(p0, p2) - Points.Distance3D(p1, p2) < 1e-3);
            }
            else
            {
                return(false);
            }
        }
示例#2
0
        /// <summary>
        /// Normalizes the points coordinates in the plane defined by the shell, and returns the holes and wall segments coordinates
        /// in this new reference system
        /// </summary>
        /// <param name="s"></param>
        /// <param name="segments"></param>
        /// <returns></returns>
        public static (List <Vertex>, GeoTransform) NormalizeShell(Shell s)
        {
            MWPoint3D X0 = s.Points[0];

            // we choose a point p0 and make sure the origin is part of the plane of the shell
            List <MWPoint3D>         cPoints      = s.Points.Select(p => new MWPoint3D(p.X - X0.X, p.Y - X0.Y, p.Z - X0.Z)).ToList();
            List <List <MWPoint3D> > cHolesPoints = s.Holes.Select(lp => lp.Select(p => new MWPoint3D(p.X - X0.X, p.Y - X0.Y, p.Z - X0.Z)).ToList()).ToList();
            List <List <MWPoint3D> > cSegPoints   = s.IncludedSegments.Select(lp => lp.Select(p => new MWPoint3D(p.X - X0.X, p.Y - X0.Y, p.Z - X0.Z)).ToList()).ToList();
            MWPoint3D p0 = new MWPoint3D(0, 0, 0);

            // we look for 2 points such that p0, p1 and p2 are not aligned
            MWPoint3D p1 = cPoints[1];
            MWPoint3D p2 = cPoints[2];

            for (int i = 2; i < cPoints.Count; i++)
            {
                p2 = cPoints[i];
                double dp = Math.Abs((p2.X - p0.X) * (p1.X - p0.X) + (p2.Y - p0.Y) * (p1.Y - p0.Y) + (p2.Z - p0.Z) * (p1.Z - p0.Z));
                if (dp < Points.Distance3D(p0, p1) * Points.Distance3D(p0, p2) - 1e-4)
                {
                    break;
                }
            }

            // we extract two normal vectors defining the plan of the shell
            MWVector3D v = new MWVector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);

            v = v.Normalised();
            MWVector3D w0 = new MWVector3D(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);
            MWVector3D n  = Vectors3D.VectorialProduct(v, w0);

            n = n.Normalised();
            MWVector3D w = Vectors3D.VectorialProduct(v, n);

            w = w.Normalised();

            Matrix <double> P = Matrix <double> .Build.DenseOfRowArrays(new[] { v.X, v.Y, v.Z },
                                                                        new[] { w.X, w.Y, w.Z },
                                                                        new[] { n.X, n.Y, n.Z });

            List <MWPoint2D> newPts = cPoints.Select(p =>
            {
                MWVector3D vp = new MWVector3D(p.X, p.Y, p.Z);
                double x      = Vectors3D.ScalarProduct(vp, v);
                double y      = Vectors3D.ScalarProduct(vp, w);
                double z      = Vectors3D.ScalarProduct(vp, n);
                //Console.WriteLine("z = {0} (should be 0)", z);
                return(new MWPoint2D(x, y));
            }).ToList();

            //List<List<MWPoint2D>> newHolesPts = cHolesPoints.Select(lp => lp.Select(p =>
            //{
            //    MWVector3D vp = new MWVector3D(p.X, p.Y, p.Z);
            //    double x = Vectors3D.ScalarProduct(vp, v);
            //    double y = Vectors3D.ScalarProduct(vp, w);
            //    double z = Vectors3D.ScalarProduct(vp, n);
            //    //Console.WriteLine("z = {0} (should be 0)", z);
            //    return new MWPoint2D(x, y);
            //}).ToList()).ToList();

            //List<List<MWPoint2D>> newSegPts = cSegPoints.Select(lp => lp.Select(p =>
            //{
            //    MWVector3D vp = new MWVector3D(p.X, p.Y, p.Z);
            //    double x = Vectors3D.ScalarProduct(vp, v);
            //    double y = Vectors3D.ScalarProduct(vp, w);
            //    double z = Vectors3D.ScalarProduct(vp, n);
            //    //Console.WriteLine("z = {0} (should be 0)", z);
            //    return new MWPoint2D(x, y);
            //}).ToList()).ToList();

            if (newPts.Any(p => double.IsNaN(p.X)))
            {
                Console.WriteLine("NaN");
            }

            double x0 = newPts.Min(p => p.X);
            double y0 = newPts.Min(p => p.Y);
            double x1 = newPts.Max(p => p.X);
            double y1 = newPts.Max(p => p.Y);

            double l = Math.Max(x1 - x0, y1 - y0);

            GeoTransform trans = new GeoTransform()
            {
                P    = P,
                X0   = X0,
                Xmin = new MWPoint2D(x0, y0),
                Xmax = new MWPoint2D(x1, y1)
            };

            return(newPts.Select(p => new Vertex((p.X - x0) / l, (p.Y - y0) / l)).ToList(),
                   trans
                   );
        }