Author Topic: Points on a line...  (Read 5234 times)

0 Members and 1 Guest are viewing this topic.

DotNetDude

  • Guest
Points on a line...
« on: December 24, 2007, 08:15:00 PM »
I have two randomly located Point3D objects, and with them I have created a new Vector3D object. I would like to create a series of Point3D objects at a given interval (say 10 units) on the imaginary line between those two points. I thought I could place new points by adjusting the length property of my Vector3D object, but it is read only.

Can anyone give me an example of how to place points along a 3D line or point me in the right direction? Is there a 3D version of the polar point function? Any help would be greatly appreciated!
« Last Edit: December 24, 2007, 08:19:13 PM by DotNetDude »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Points on a line...
« Reply #1 on: December 25, 2007, 01:04:32 AM »
There are several ways to determine the points.
Have a play with this for one way using Vector Geometry.
Code: [Select]
/********************************************************************
created: 2007-12-25 15:56
file path: .....\Visual Studio 2008\CAD Projects\VectorTest02\VectorTest02
file base: Commands.cs
CodeHimBelonga: kwb

Description: Test Routine for theswamp forum question
     http://www.theswamp.org/index.php?topic=20656.msg251042#msg251042
*********************************************************************/

using System;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using Acdb = Autodesk.AutoCAD.DatabaseServices;


[assembly: CommandClass(typeof(VectorTest02.TestCommands))]

namespace VectorTest02
{
    /// <summary>
    /// Summary description for TestCommands Class.
    /// </summary>
    public class TestCommands
    {
        [CommandMethod("VT02")]
        static public void test()
        {   
            Document Doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor Ed = Doc.Editor;           
           
            PromptPointResult ppr1 = Ed.GetPoint("\Select the Vector Origin Point: ");

            PromptPointOptions ppo2 = new PromptPointOptions("\nSelect second point: ");
            ppo2.BasePoint = ppr1.Value;
            ppo2.UseBasePoint = true;
            ppo2.UseDashedLine = true;
            PromptPointResult ppr02 = Ed.GetPoint(ppo2);

            Point3d pt1 = ppr1.Value;
            Point3d pt2 = ppr02.Value;
            Vector3d vec3d = (Vector3d)(pt2 - pt1);           
            //
            PromptDistanceOptions pdo1 = new PromptDistanceOptions("\nSpacing along Vector: ");
            pdo1.AllowNegative = false;
            pdo1.AllowZero = false;
            pdo1.AllowNone = false;
            pdo1.UseDashedLine = true;
            pdo1.DefaultValue = 10.0;
            PromptDoubleResult res = Ed.GetDistance(pdo1);

            Double spacingDistance = res.Value;
            Double wpDistance = pt1.DistanceTo(pt2);
            //
            Ed.WriteMessage("\nDistance: {0} \nSpacing: {1} \nVector: {2}",
                wpDistance.ToString(),
                spacingDistance.ToString(),
                vec3d.ToString()
                );

            Vector3d spacingVector = vec3d.MultiplyBy(spacingDistance / wpDistance);
            Ed.WriteMessage("\nspacingVector: {0} \nspacingVectorDistance {1}",
                spacingVector.ToString(),
                spacingVector.Length.ToString()               
                );

            int steps = (int)(wpDistance / spacingDistance);
            Point3dCollection PointList = new Point3dCollection();
            for (int i = 1 ; i <= steps ; i++)
            {
                Point3d nextPoint = pt1.Add(spacingVector.MultiplyBy(i));
                PointList.Add(nextPoint);
            }
            foreach ( Point3d pt in PointList )
            {
                Ed.WriteMessage("\nPoint: {0}",
                    pt.ToString()
                    );
            }
        }
    }
}

Piccy added (log-In to view)
« Last Edit: December 25, 2007, 02:35:53 AM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Points on a line...
« Reply #2 on: December 25, 2007, 01:42:19 AM »
.. so a 3DPolar method could look something like this ;

 
Code: [Select]
       /// <summary>
        /// PolarPoint3D
        /// </summary>
        /// <param name="Point3d pt1"></param>
        /// <param name="Point3d pt2"></param>
        /// <param name="Double dist"></param>
        /// <returns>3D polar Point3d In the CURRENT UCS</returns>
        static public Point3d PolarPoint3D(Point3d pt1, Point3d pt2, Double dist )
        {           
            Vector3d vec3d = (Vector3d)(pt2 - pt1);
            return pt1.Add(vec3d.MultiplyBy(dist / vec3d.Length));
        }

and called like this ( add method and call to the previous class )

Code: [Select]
            Double step3d = Ed.GetDistance("\nEnter 3D Polar Distance: ").Value;
            Point3d pt3 = PolarPoint3D(pt1, pt2, step3d);
            Ed.WriteMessage("\n3D PolarPoint: {0}",
                                pt3.ToString()
                                );
« Last Edit: December 25, 2007, 01:46:56 AM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Points on a line...
« Reply #3 on: December 25, 2007, 02:07:24 AM »

.. though it's not really a polar Point routine, so the method may be better named getPointByVector (or somesuch ) :-)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Points on a line...
« Reply #4 on: December 25, 2007, 05:26:16 AM »
... and to translate the points from UCS to WCS
using these Extension Methods :-

/********************************************************************
   created:   2007-12-25 20:13
   file path:   ..\Visual Studio 2008\CAD Projects\kdubToolKit\kdubToolKit
   file base:   kdubExtensions.cs
   CodeHimBelonga:   kwb
   
   Description:
*********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcEd = Autodesk.AutoCAD.EditorInput;

namespace kdubExtensions
{
    public static partial class dbExtensions
    {
        public static Point3d UcsToWcs(this Point3d pt, AcDb.Database db)
        {
            return pt.TransformBy(db.GetUcsMatrix());
        }
        public static bool IsPaperSpaceActive(this AcDb.Database db)
        {
            if (db.TileMode)
            {
                return false;
            }
            return (db.PaperSpaceVportId == AcadApp.DocumentManager.MdiActiveDocument.
                                                          Editor.CurrentViewportObjectId);
        }
        public static Matrix3d GetUcsMatrix(this AcDb.Database db)
        {
            Point3d ucsorgin = db.Ucsorg;
            Vector3d ucsxdir = db.Ucsxdir;
            Vector3d ucsydir = db.Ucsydir;
            // re-assign variables if PaperSpace is Active
            if (db.IsPaperSpaceActive())
            {
                ucsorgin = db.Pucsorg;
                ucsxdir = db.Pucsxdir;
                ucsydir = db.Pucsydir;
            }
            // Vector3d newZAxis = ucsxdir.CrossProduct(ucsydir);
            return Matrix3d.AlignCoordinateSystem(Point3d.Origin,
                Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis,
                ucsorgin, ucsxdir, ucsydir, ucsxdir.CrossProduct(ucsydir));
        }
    }
}


Revised Sample Code

/********************************************************************
   created:   2007-12-25 15:56
    revised:   [kwb 2007-12-25 20:22]
   file path:   .....\Visual Studio 2008\CAD Projects\VectorTest02\VectorTest02
   file base:   Commands.cs
   CodeHimBelonga:   kwb
   
   Description: Test Routine for theswamp forum question
     http://www.theswamp.org/index.php?topic=20656.msg251042#msg251042
*********************************************************************/

using System;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcEd = Autodesk.AutoCAD.EditorInput;
//
using kdubExtensions;

[assembly: CommandClass(typeof(VectorTest02.TestCommands))]

namespace VectorTest02
{
    public class TestCommands
    {
        /// <summary>
        /// GetPointOnVector
        /// </summary>
        /// <param name="Point3d pt1"></param>
        /// <param name="Point3d pt2"></param>
        /// <param name="Double dist"></param>
        /// <returns>3D polar Point3d </returns>
        static public Point3d GetPointOnVector(Point3d pt1, Point3d pt2, Double dist)
        {
            Vector3d vec3d = (Vector3d)(pt2 - pt1);
            return pt1.Add(vec3d.MultiplyBy(dist / vec3d.Length));
        }


        [CommandMethod("VT02")]
        static public void test()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Database db = AcDb.HostApplicationServices.WorkingDatabase;
            Editor ed = doc.Editor;
            //
            PromptPointResult ppr1 = ed.GetPoint("\nSelect the first point Vector: ");

            PromptPointOptions ppo2 = new PromptPointOptions("\nSelect second point: ");
            ppo2.BasePoint = ppr1.Value;
            ppo2.UseBasePoint = true;
            ppo2.UseDashedLine = true;
            PromptPointResult ppr02 = ed.GetPoint(ppo2);

            Point3d pt1 = ppr1.Value;
            Point3d pt2 = ppr02.Value;
            Vector3d vec3d = (Vector3d)(pt2 - pt1);
            //
            PromptDistanceOptions pdo1 = new PromptDistanceOptions("\nSpacing along Vector: ");
            pdo1.AllowNegative = false;
            pdo1.AllowZero = false;
            pdo1.AllowNone = false;
            pdo1.UseDashedLine = true;
            pdo1.DefaultValue = 10.0;
            PromptDoubleResult res = ed.GetDistance(pdo1);

            Double spacingDistance = res.Value;
            Double wpDistance = pt1.DistanceTo(pt2);
            //
            ed.WriteMessage("\nDistance: {0} \nSpacing: {1} \nVector: {2}",
                wpDistance.ToString(),
                spacingDistance.ToString(),
                vec3d.ToString()
                );

            Vector3d spacingVector = vec3d.MultiplyBy(spacingDistance / wpDistance);
            ed.WriteMessage("\nspacingVector: {0} \nspacingVectorDistance {1}",
                spacingVector.ToString(),
                spacingVector.Length.ToString()
                );

            int steps = (int)(wpDistance / spacingDistance);
            Point3dCollection PointList = new Point3dCollection();
            for (int i = 1; i <= steps; i++)
            {
                Point3d nextPoint = pt1.Add(spacingVector.MultiplyBy(i));
                PointList.Add(nextPoint);
            }
            foreach (Point3d pt in PointList)
            {
                ed.WriteMessage("\nPoint: {0}",
                    pt.ToString()
                    );
            }
            //
            //
            Double step3d = ed.GetDistance("\nEnter 3D Polar Distance: ").Value;
            Point3d pt3 = GetPointOnVector(pt1, pt2, step3d);
            ed.WriteMessage("\n3D PolarPoint: {0} \nTranslated to WCS: {1}",
                pt3.ToString(),
                pt3.UcsToWcs(db).ToString()
                );
        }
    }
}
« Last Edit: December 25, 2007, 05:33:09 AM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Points on a line...
« Reply #5 on: December 25, 2007, 07:58:09 AM »
for those who don't get out much ..
a solution from Tony Tanzillo at autodesk.autocad.customization.dotnet ( thread titled 'Vector3D Question' news:5807618@discussion.autodesk.com)
.. just goes to show that it helps to know the API intimately and/or know the ARX classes :-)

            //
            //
            double distanceToPoint = ed.GetDistance("\nEnter 3D Polar Distance: ").Value;
            LineSegment3d line = new LineSegment3d ( pt1, pt2 );
            Point3d pointOnLine = line.EvaluatePoint ( distanceToPoint / line.Length );
            ed.WriteMessage("\n3D PolarPoint: {0} \nTranslated to WCS: {1}",
                pointOnLine.ToString(),
                pointOnLine.UcsToWcs(db).ToString()
                );


The LineSegment3d is from the Autodesk.AutoCAD.Geometry namespace and doesn't get added to the database.
I thought it may fail if the 'point' didn't fall ON the 'line', but that's not the case ; the 'distanceToPoint' variable can be a negative value or exceed the actual line length ( similar to a vector solution)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8690
  • AKA Daniel
Re: Points on a line...
« Reply #6 on: December 25, 2007, 08:33:59 AM »
Wow! Kerry,  You’ve only had your C# books for three weeks and now your kicking code out like a master! 8-)


Welcome to the Swamp DotNetDude,
« Last Edit: December 25, 2007, 08:40:00 AM by Daniel »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Points on a line...
« Reply #7 on: December 25, 2007, 09:05:08 AM »

....   You’ve only had your C# books for three weeks ...........


Nah ! I'm trying to pick up where I left off last year ; but the new books are helping me focus ... 'master' ?, Hah ! perhaps in a couple of years ;-) 
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

DotNetDude

  • Guest
Re: Points on a line...
« Reply #8 on: December 25, 2007, 09:35:19 AM »
Thank you so much Kerry! Your GetPointOnVector function is exactly what I was looking for. It's almost too good!

Thank you Daniel. I can tell this is this is a great forum and I look forward to spending allot of time here!

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Points on a line...
« Reply #9 on: December 25, 2007, 09:43:07 AM »
You're welcome 'Dude.
:-)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.