public void CDS_FindClosestPointOnSurface()
        {
            ObjectId surfaceId = promptForTinSurface();

            if (surfaceId.IsNull)
            {
                write("\nNo TIN Surface selected.");
                return;
            }

            PromptPointResult result = _editor.GetPoint(
                "\nSelect point outside surface: ");

            if (result.Status != PromptStatus.OK)
            {
                write("\nNo point selected.");
                return;
            }

            Point3d selectedPoint         = result.Value;
            Point3d closestPointFound     = Point3d.Origin;
            double  shortestDistanceSoFar = Double.MaxValue;

            using (Transaction tr = startTransaction())
            {
                TinSurface surface = surfaceId.GetObject(OpenMode.ForRead)
                                     as TinSurface;
                write("\nSelected surface: " + surface.Name);
                write("\nSelected point: " + selectedPoint.ToString());
                ObjectIdCollection borders = surface.ExtractBorder(
                    SurfaceExtractionSettingsType.Model);
                foreach (ObjectId borderId in borders)
                {
                    Polyline3d border = borderId.GetObject(OpenMode.ForRead)
                                        as Polyline3d;
                    Point3d closestToBorder =
                        border.GetClosestPointTo(selectedPoint, false);
                    double distance = selectedPoint.DistanceTo(closestToBorder);
                    if (distance < shortestDistanceSoFar)
                    {
                        closestPointFound     = closestToBorder;
                        shortestDistanceSoFar = distance;
                    }
                }
            }

            write("\nClosest point found: " + closestPointFound.ToString());

            using (Transaction tr = startTransaction())
            {
                BlockTableRecord btr = tr.GetObject(_database.CurrentSpaceId,
                                                    OpenMode.ForWrite) as BlockTableRecord;
                Line line = new Line(selectedPoint, closestPointFound);
                btr.AppendEntity(line);
                tr.AddNewlyCreatedDBObject(line, true);
                tr.Commit();
            }
        }
Ejemplo n.º 2
0
        public static Point3d FindClosestPoint(Transaction trans, ObjectId idA, ObjectId idB)
        {
            Polyline3d curveA = trans.GetObject(idA, OpenMode.ForRead) as Polyline3d;
            Polyline3d curveB = trans.GetObject(idB, OpenMode.ForRead) as Polyline3d;

            double  distance = double.MaxValue;
            Point3d result   = Point3d.Origin;

            for (double param = curveA.StartParam; param < curveA.EndParam; param += ((curveA.EndParam - curveA.StartParam) / 100))
            {
                Point3d pointOnA        = curveA.GetPointAtParameter(param);
                Point3d closestPointOnB = curveB.GetClosestPointTo(pointOnA, false);

                double distanceBetweenPoints = pointOnA.DistanceTo(closestPointOnB);
                if (distanceBetweenPoints < distance)
                {
                    distance = distanceBetweenPoints;
                    result   = pointOnA; // equals closestPointOnB
                }
            }

            return(result);
        }
Ejemplo n.º 3
0
        ///<summary>
        /// Get the intersection points between this planar entity and a curve.
        ///</summary>
        ///<param name="cur">The curve to check intersections against.</param>
        ///<returns>An array of Point3d intersections.</returns>
        public static Point3d IntersectWith(Point3d pt, Vector3d vect, Polyline3d poly0, Polyline3d poly, double testWidth, Document doc)
        {
            Database db = doc.Database;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable       bt  = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false);

                string layerName = CreateAndAssignALayer(Setting.defaultLayerName);//incase if this layer not exist
                if (layerName == string.Empty)
                {
                    layerName = "0";
                }

                #region create a 2d line on XY plane in order to find the intersect point for on TBM centerline
                //create a 2d point
                Point3d pt0 = new Point3d(pt.X, pt.Y, 0);

                Vector3d v   = vect.GetNormal() * testWidth;
                Matrix3d mat = Matrix3d.Displacement(v);
                Point3d  npt = pt0.TransformBy(mat);

                v   = vect.GetNormal() * -testWidth;
                mat = Matrix3d.Displacement(v);
                Point3d npt1 = pt0.TransformBy(mat);

                //create a 2d line in XY plane and add to drawing, this use to intersect with TBM alignment, so I can find the point in TBM alignment to create circle
                Line ln = new Line(npt, npt1);
                ln.Layer = layerName;
                btr.AppendEntity(ln);
                tr.AddNewlyCreatedDBObject(ln, true);

                //get the alignment object and find the nearest point to the nominated point
                Point3dCollection pts3D = new Point3dCollection();

                Point3d pt_intersect_in_TBM = Point3d.Origin;
                try
                {
                    poly0.IntersectWith(ln, Intersect.OnBothOperands, pts3D, IntPtr.Zero, IntPtr.Zero);

                    if (pts3D.Count > 0)
                    {
                        Point3d p     = pts3D[0];
                        DBPoint db_pt = new DBPoint(p);
                        db_pt.Layer = layerName;
                        btr.AppendEntity(db_pt);
                        tr.AddNewlyCreatedDBObject(db_pt, true);

                        try
                        {
                            double para = poly0.GetParameterAtPoint(pts3D[0]);//this is where it will fail, don't know why!
                            //ed.WriteMessage($"{pts3D[0]}, {para}\n");
                            pt_intersect_in_TBM = poly.GetPointAtParameter(para);
                            return(pt_intersect_in_TBM);
                        }
                        catch
                        {
                            pt_intersect_in_TBM = poly.GetClosestPointTo(p, Vector3d.ZAxis, true);//when GetParameterAtPoint fail, this is should work. but use in caution!
                        }
                    }
                    #endregion
                }
                catch { }

                tr.Commit();

                return(pt_intersect_in_TBM);
            }
        }