Author Topic: Pick points to 2dpoints.  (Read 8163 times)

0 Members and 1 Guest are viewing this topic.

Bryco

  • Water Moccasin
  • Posts: 1883
Pick points to 2dpoints.
« on: December 18, 2007, 12:12:24 AM »
I'm having a bit of trouble figuring out planes.
I'm picking 3d points and I want to make them 2d for polyline coords.
I presume the plane needed is the
Plane pn = new Plane(db.Ucsorg, db.Ucsxdir.CrossProduct(db.Ucsydir));
as I want to add the pline in the current ucs.
Any combo of Point2d P = Res1.Value.Convert2d(pn); or
Point2d P = Res1.Value.TransformBy(ucs).Convert2d(pn); fails with a curly Ucs
In vba one translates the points to the plines ocs using the normal.
Is it the same in c#?
(I've tried Kean Walmsley's poly jig and that doesn't work either.)
some mess around code
Code: [Select]
[CommandMethod("Dp")]
        public void PlineDraw2()
        {
           
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            Polyline oPline = new Polyline(3);
            ObjectId id = ObjectId.Null;


            Plane pn = new Plane(db.Ucsorg, db.Ucsxdir.CrossProduct(db.Ucsydir));
            //Plane pn = new Plane(db.Ucsorg, new Vector3d(0,0,1));
            Transaction tr = null;
            Matrix3d ucs = ed.CurrentUserCoordinateSystem;
            Vector3d Norm = new Vector3d(0, 0, 1).TransformBy(ucs);
            oPline.Normal = Norm;
            //oPline.Elevation = db.Ucsorg.Z;
            //oPline.Elevation = -pn.Coefficients.D;
            //ed.WriteMessage("\nelev={0}", -pn.Coefficients.D);
            //Point3d O = db.Ucsorg;
            //ed.WriteMessage("\nucsOrigin={0},{1},{2}", O.X, O.Y,O.Z);
         
            PromptPointResult Res1 = ed.GetPoint("\nSpecify start point:");
            if (Res1.Status != PromptStatus.OK) return;
            ed.WriteMessage("\nP={0},{1},{2}", Res1.Value.X, Res1.Value.Y, Res1.Value.Z);
           // Point2d P = Res1.Value.Convert2d(pn);
            Point2d  P = new Point2d(Res1.Value.X, Res1.Value.Y);
            ed.WriteMessage("\nP={0},{1}", P.X, P.Y);


             //P = Res1.Value.TransformBy(ucs).Convert2d(pn);
            //Point2d P = Res1.Value.Convert2d(pn);
            ed.WriteMessage("\nP={0},{1}", P.X, P.Y);

            oPline.AddVertexAt(0, P, 0, 0, 0);
             
   

            Point3d BasePt = Res1.Value;//.TransformBy(ucs);

            PromptPointOptions PPO = new PromptPointOptions("\nSpecify next point or [Arc]:", "Arc");
            PPO.UseBasePoint = true;
            PPO.UseDashedLine = true;
            PPO.AllowNone = true;
            PPO.BasePoint = BasePt;
            PromptPointResult Res2 = ed.GetPoint(PPO);
            if (Res2.Status != PromptStatus.OK) return;




            //P = Res2.Value.TransformBy(ucs).Convert2d(pn);
            //ed.WriteMessage("\nP={0},{1}", P.X, P.Y);
             //P = Res2.Value.Convert2d(pn);
             P = new Point2d(Res2.Value.X, Res2.Value.Y);
            oPline.AddVertexAt(1, P, 0, 0, 0);


            try    //add verticies
            {
                using (tr = db.TransactionManager.StartTransaction())
                {
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                    btr.AppendEntity(oPline);
                    tr.AddNewlyCreatedDBObject(oPline, true);
                    tr.Commit();
                    id = oPline.ObjectId;
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: " + ex.Message);
                tr.Abort();
            }
            finally
            {
                if (tr != null) tr.Dispose();
            }


        }



T.Willey

  • Needs a day job
  • Posts: 5251
Re: Pick points to 2dpoints.
« Reply #1 on: December 18, 2007, 01:41:19 PM »
The problem might be with your AddVertexAt method calls.  Example
Code: [Select]
            oPline.AddVertexAt(0, P, 0, 0, 0);
I think it should be
Code: [Select]
            oPline.AddVertexAt(0, P, 0.0, 0.0, 0.0);
Since it wants 'double's in those locations.
Quote
public void AddVertexAt(int index, Point2d pt, double bulge, double startWidth, double endWidth);

Only thing I can see, without running the code.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #2 on: December 18, 2007, 04:21:09 PM »
No it runs fine and works fine in world ucs or any world ucs that has been rotated about the z

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Pick points to 2dpoints.
« Reply #3 on: December 18, 2007, 06:00:50 PM »
Here is what worked for me (plus some stuff I tried).

Edit:  Now it is not working.  Back to the drawing board.
Code: [Select]
[CommandMethod("MyTestPline")]
public void MyTestPline() {
Document Doc = AcadApp.DocumentManager.MdiActiveDocument;
Database Db = Doc.Database;
Editor Ed = Doc.Editor;
PromptPointResult ppr01 = Ed.GetPoint("\nSelect first point: ");
PromptPointOptions ppo02 = new PromptPointOptions("\nSelect second point: ");
ppo02.UseBasePoint = true;
ppo02.BasePoint = ppr01.Value;
PromptPointResult ppr02 = Ed.GetPoint(ppo02);
PromptPointOptions ppo03 = new PromptPointOptions("\nSelect last point: ");
ppo03.UseBasePoint = true;
ppo03.BasePoint = ppr02.Value;
PromptPointResult ppr03 = Ed.GetPoint(ppo03);
Ed.WriteMessage("\n1 = {0}\n2 = {1}\n3 = {2}", ppr01.Value, ppr02.Value, ppr03.Value);
Vector3d vec = new Vector3d(0,0,1).TransformBy(Ed.CurrentUserCoordinateSystem);
Plane plane = new Plane(Db.Ucsorg,vec);
Ed.WriteMessage("\n{0}", vec);
//Point2d p01 = ppr01.Value.Convert2d(plane);
//Point2d p02 = ppr02.Value.Convert2d(plane);
//Point2d p03 = ppr03.Value.Convert2d(plane);
//Point3d p01 = ppr01.Value.TransformBy(Ed.CurrentUserCoordinateSystem);
//Point3d p02 = ppr02.Value.TransformBy(Ed.CurrentUserCoordinateSystem);
//Point3d p03 = ppr03.Value.TransformBy(Ed.CurrentUserCoordinateSystem);
//Ed.WriteMessage("\n1 = {0}\n2 = {1}\n3 = {2}", p01, p02, p03);
Polyline Pline = new Polyline(3);
//Pline.AddVertexAt(0, new Point2d(p01.X, p01.Y), 0.0, 0.0, 0.0);
//Pline.AddVertexAt(0, new Point2d(p02.X, p02.Y), 0.0, 0.0, 0.0);
//Pline.AddVertexAt(0, new Point2d(p03.X, p03.Y), 0.0, 0.0, 0.0);
//Pline.AddVertexAt(0, p01, 0.0, 0.0, 0.0);
//Pline.AddVertexAt(0, p02, 0.0, 0.0, 0.0);
//Pline.AddVertexAt(0, p03, 0.0, 0.0, 0.0);
Pline.AddVertexAt(0, new Point2d(ppr01.Value.X, ppr01.Value.Y), 0.0, 0.0, 0.0);
Pline.AddVertexAt(0, new Point2d(ppr02.Value.X, ppr02.Value.Y), 0.0, 0.0, 0.0);
Pline.AddVertexAt(0, new Point2d(ppr03.Value.X, ppr03.Value.Y), 0.0, 0.0, 0.0);
Pline.Normal = vec;
using (Transaction Trans = Db.TransactionManager.StartTransaction()) {
BlockTableRecord btr = (BlockTableRecord)Trans.GetObject(Db.CurrentSpaceId, OpenMode.ForWrite);
btr.AppendEntity(Pline);
Trans.AddNewlyCreatedDBObject(Pline, true);
Trans.Commit();
}

}
« Last Edit: December 18, 2007, 06:10:46 PM by T.Willey »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #4 on: December 18, 2007, 07:15:19 PM »
Thanks for trying Tim.
It seems like the easiest thing (I still hope it is) but there are so many variables.
I have everything working on the polyline jig but this (The 3d part), and I thought this would be the easiest.
Although for some reason the jig gives points in world just to totally confuse you.
Perhaps using a plane is a mistake.
Theoretically if you were to pick 4 points and the returns are in Ucs then using those numbers (say the z is 0)
to input as coordinates, make the pline and transform the whole pline with the ucsmatrix you would get the correct result (It sounds good I don't know.)
That transformation is a bit like , use the 2d points to make the pline, then set the normal and the elevation (if the ucs origin was 0,0,0 this may be the same)
The normal should be the ucs crossproduct, the elevation is probably the vector distance from the ucs origin to 0,0,0.
I think if you use ppr01.Value.Convert2d(plane); you are effectively getting the res value, converting it to world, converting that back to the same plane as the ucs.

I'll work some more on it tonight, as I said in vba I make an ocs but I haven't seen that used in C# so far.

Glenn R

  • Guest
Re: Pick points to 2dpoints.
« Reply #5 on: December 19, 2007, 06:27:15 AM »
Bryco,

Is this Kean's post you're referring to?

Cheers,
Glenn.

Glenn R

  • Guest
Re: Pick points to 2dpoints.
« Reply #6 on: December 19, 2007, 08:06:14 AM »
Bryco,

That post by Kean I linked above, seems to be doing, as they say over here, 'what it says on the tin', even with really squirly rotated and twisted UCS's. I used 'vpoint' to change the the view to something really funny, the did a 'ucs v' and it all looks ok...

Cheers,
Glenn.

Fatty

  • Guest
Re: Pick points to 2dpoints.
« Reply #7 on: December 19, 2007, 08:50:19 AM »
Here is similar on what you needed
but without jigg :)

Code: [Select]
Imports System
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.GraphicsInterface
Imports Autodesk.AutoCAD.ApplicationServices.Application
Imports AcadRT = Autodesk.AutoCAD.Runtime
Imports AcadED = Autodesk.AutoCAD.EditorInput
Imports AcadDB = Autodesk.AutoCAD.DatabaseServices
Imports AcadApp = Autodesk.AutoCAD.ApplicationServices.Application

Public Class PlineUtils
    <CommandMethod("TP")> _
    Public Sub InteractPline()
        Dim adoc As Autodesk.AutoCAD.ApplicationServices.Document = AcadApp.DocumentManager.MdiActiveDocument
        Dim db As Database = adoc.Database
        Dim ed As Editor = adoc.Editor

        Dim vec As Vector3d = New Vector3d(0, 0, 1).TransformBy(ed.CurrentUserCoordinateSystem)
        Dim plane As Plane = New Plane(db.Ucsorg, vec)
        Dim res1 As PromptPointResult = ed.GetPoint(ControlChars.CrLf & "Select first point: ")

        Dim bp As Point3d = New Point3d(res1.Value.X, res1.Value.Y, res1.Value.Z)
        Dim ar As ArrayList = New ArrayList
        ar.Add(bp.X)
        ar.Add(bp.Y)
        Dim res2 As PromptPointResult
        Dim n As Integer = 0

        Do
            Dim opt As PromptPointOptions = New PromptPointOptions(ControlChars.CrLf & "Select next point: ")

            opt.AppendKeywordsToMessage = True
            opt.UseBasePoint = True
            opt.BasePoint = bp
            opt.AllowArbitraryInput = True
            opt.SetMessageAndKeywords(ControlChars.CrLf & "Select next point: " & "Or Yes to Exit [Y/N]", "Yes No")
            res2 = ed.GetPoint(opt)
            bp = New Point3d(res2.Value.X, res2.Value.Y, res2.Value.Z)
            ar.Add(bp.X)
            ar.Add(bp.Y)
            n += 1
        Loop Until res2.Status = PromptStatus.Keyword

        Dim Pline As Polyline = New Polyline(n)
        For i As Integer = 0 To ar.Count - 1 Step 2
            Pline.AddVertexAt(0, New Point2d(ar(i), ar(i + 1)), 0.0, 0.0, 0.0)
        Next i

        Pline.Normal = vec
        Pline.RemoveVertexAt(0)

        Using tr As Transaction = db.TransactionManager.StartTransaction()
            Dim btr As BlockTableRecord = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
            btr.AppendEntity(Pline)
            tr.AddNewlyCreatedDBObject(Pline, True)
            tr.Commit()
        End Using

    End Sub

~'J'~

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #8 on: December 19, 2007, 11:15:38 AM »
Glenn, yes that one.
In the dwg enclosed, if you run mypoly and trce over the rectangle you will see it doesn't line up.  Actually it only needs the elevation set and adding the code below makes it work
Code: [Select]
// Create polyline, set defaults, add dummy vertex

                Polyline pline = Entity as Polyline;

                pline.SetDatabaseDefaults();

                pline.Normal = normal;

                Plane pn = new Plane         (ucs.CoordinateSystem3d.Origin,normal);///////////////////////
                pline.Elevation = -pn.Coefficients.D;//////////////////

                AddDummyVertex();

Perhaps this will help, but all the points given from the jig are in Wcs not Ucs.

Fatty, I don't have vb (the temptation was too great). I'll put that in C# tonight and see if it works

Glenn R

  • Guest
Re: Pick points to 2dpoints.
« Reply #9 on: December 19, 2007, 03:52:36 PM »
Yep. It created the polyline exactly as i thought it would. I listed the object you have previously drawn and it gives an extrusion direction - which immediately tells me, that it's not coplanar to the current UCS.

I think you're confusing the creation (programmatically) of a polyline (lightweight - which must have all points coplanar) and going tracing over that polyline which is NOT coplanar to the current UCS in your drawing.

If you wanted to trace over that polyline you have existing, then I think you would need a 3d poly or is it Polyline3d...can't remember.

Does that make sense?

Cheers,
Glenn.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #10 on: December 19, 2007, 05:27:16 PM »
Dang I posted the drawing with the wrong ucs. (Stomps foot)
This one has the ucs per object.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #11 on: December 19, 2007, 08:55:07 PM »
Fatty thanks for trying but if below is a correct translation, it doesn't do it either .
Code: [Select]
namespace Fatty
{
   
public class PlineUtils
{
    [CommandMethod("TP")]

    public void InteractPline()
    {
        Autodesk.AutoCAD.ApplicationServices.Document adoc= AcadApp.DocumentManager.MdiActiveDocument;
        Database db= adoc.Database;
        Editor ed= adoc.Editor;
       
        Vector3d vec= new Vector3d(0, 0, 1).TransformBy(ed.CurrentUserCoordinateSystem);
        Plane plane= new Plane (db.Ucsorg, vec);
        PromptPointResult res1= ed.GetPoint( "\nSelect first point: ");

        Point3d bp= new Point3d(res1.Value.X, res1.Value.Y, res1.Value.Z);
       
        ArrayList ar= new ArrayList();
        ar.Add(bp.X);
        ar.Add(bp.Y);
        PromptPointResult res2;
        int n  = 0;
       
        do
        {
            PromptPointOptions opt= new PromptPointOptions("Select next point: ");
            opt.AppendKeywordsToMessage = true;
            opt.UseBasePoint = true;
            opt.BasePoint = bp;
            opt.AllowArbitraryInput = true;
            opt.SetMessageAndKeywords( "Select next point: Or Yes to Exit [Y/N]", "Yes No");
            res2 = ed.GetPoint(opt);
            //bp = new Point3d(res2.Value.X, res2.Value.Y, res2.Value.Z);
            bp = res2.Value;
            ar.Add(bp.X);
            ar.Add(bp.Y);
            n ++;
       
        }
        while (res2.Status != PromptStatus.Keyword);

        Polyline Pline   =new Polyline(n);
        for(int i  = 0; i< ar.Count ; i+=2)
            Pline.AddVertexAt(0, new Point2d((double)ar[i], (double)ar[i + 1]), 0.0, 0.0, 0.0);

        Pline.Normal = vec;
        Pline.RemoveVertexAt(0);
        using ( Transaction tr = db.TransactionManager.StartTransaction())
        {
            BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
            btr.AppendEntity(Pline);
            tr.AddNewlyCreatedDBObject(Pline, true);
            tr.Commit();
        }
    }

   
    }
}

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #12 on: December 19, 2007, 10:31:09 PM »
Got it. Thanks for the help all.
1) Get the current ucs
            Matrix3d ucs = ed.CurrentUserCoordinateSystem;

 2) Get the ucs normal       
            Vector3d Norm = new Vector3d(0, 0, 1).TransformBy(ucs);

3) Make a plane using 0,0,0 as the origin
            Plane pn = new Plane(new Point3d(0, 0, 0), Norm);

4) Set the pline normal           
            oPline.Normal = Norm;

5 )Set the pline elevation using the distance of the current ucs from (0,0,0)
            Plane pn2 = new Plane(ucs.CoordinateSystem3d.Origin, Norm);
            oPline.Elevation = -pn2.Coefficients.D;

6) Convert the picked point to wcs then convert it to a 2d point
            Point2d   P = Res1.Value.TransformBy(ucs).Convert2d(pn);
       

Glenn R

  • Guest
Re: Pick points to 2dpoints.
« Reply #13 on: December 20, 2007, 05:03:08 AM »
Nice one Bryco, but how on earth did you come up with it?

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #14 on: December 20, 2007, 07:53:03 AM »
There's no math in vba as you know, so I have done this before, but I didn't know how net does it. As far as really understanding it I don't.
I wrote a sub to give  the rectangle a normal of 0,0,1 and that has the coordinates I need to put in.
Since normals and elevations are all related to 0,0,0 it makes sense to use 0,0,0 as the origin.
To check things I wrote the following
Code: [Select]
    [CommandMethod("rep")]
        public void PlineDraw4()
        {

            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityResult E = ed.GetEntity("Poly");
            ObjectId id = E.ObjectId;
            Point2dCollection P = new Point2dCollection();
            Vector3d Norm = new Vector3d();
            Point2d d = new Point2d();
            double el;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                Polyline oPline = (Polyline)tr.GetObject(id, OpenMode.ForRead);
                Norm = oPline.Normal;
                el = oPline.Elevation;
                for (int i = 0; i < oPline.NumberOfVertices; i++)
                {
                    P.Add(oPline.GetPoint2dAt(i));
                    d = oPline.GetPoint2dAt(i);
                    ed.WriteMessage("\nP1={0},{1}", d.X, d.Y);
                }
                tr.Abort();
            }
           
            Polyline P2 = new Polyline(3);
         

            for (int i = 0; i < P.Count; i++)
            {
                P2.AddVertexAt(i, P[i], 0, 0, 0);

            }
            P2.Closed = true;
            P2.Normal = Norm;
            P2.Elevation = el;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                btr.AppendEntity(P2);
                tr.AddNewlyCreatedDBObject(P2,true);
             
                tr.Commit();
            }

        }

The 2d points (GetPoint2dAt(i)) that this prints out when you run it on the drawing provided are the same as those listed in the property box (set the ucs to wcs for this) for the rectangle with the 0,0,1 normal. Whereas the property box gives a lying ass reading for the rectangle as drawn. The 2d points should read the same no matter what the normal or elevation is.

So with a plane that cuts through 0,0,0 we have effectively layed the rectangle onto a world plane (but up or down in the z by it's elevation) so the 2d points will be true.
Ax+ By + Cz + d = 0 formula for a plane where d=-oLWP.Elevation
So the .Coefficients.D looked like the ticket.

Glenn R

  • Guest
Re: Pick points to 2dpoints.
« Reply #15 on: December 20, 2007, 08:01:18 AM »
 :-o I'll take your word for it. Good one.

Cheers,
Glenn.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8764
  • AKA Daniel
Re: Pick points to 2dpoints.
« Reply #16 on: December 20, 2007, 08:35:55 AM »
There's no math in vba as you know, so I have done this before, .....
....So the .Coefficients.D looked like the ticket.

<Wayne’s World> "Wow! You're.... amazing, man." </Wayne’s World>

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #17 on: December 20, 2007, 09:45:38 AM »
Thanks guys. I appreciate it.
But I've been working on this for  ever now.
Since Glenn helped me with a circle jig I thought I'ld bang out the poly jig.
I keep getting so close (Oh yeah, I'll have this sewn up in a jiffy) and then whatever I fixed something worse comes along. I did see Kean's post pretty early but didn't take it in too much as I wanted to do it on my own.
There's a couple of things he did that looked a bit funny so I took another tack (I didn't want to make a dummy polyline) however the way jigs differ from other code I think he took the sensible rout.
This works pretty good on the 2d and works for a bit on the 3d then throws a wobbler.

Code: [Select]
using System;
using System.Windows.Forms;
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;

namespace Plinejigging
{
    public class PlineJiggy
    {

        public class PolyArcJiggy
        {

            public class PolyArcJig : EntityJig
            {
                private Point2d startP, endP, FirstPt, midPt;
                private Vector3d _normal;
                private double sAng, eAng;
                private Plane pn;
                private Point3d BasePt, SecondPt, endP3d, Cen3d;
                private Util.MyMath.Slope S2;
                private int i, Vcnt;
                private PromptPointResult dres;
                private bool bSecondPt = false;
                private double El;

                public PolyArcJig(Vector3d Normalvec, int iVertex,
                        Point3d BaseP, Vector3d Firstderiv,
                        Plane oPlane,double Elev, bool bSecond)
                    : base(new Arc())
                {
                    Vcnt = iVertex;
                    pn = oPlane;
                    BasePt = BaseP; //Still need a point in ucs for prompts
                    startP = BasePt.Convert2d(pn);
                    Vector3d V = Firstderiv;
                    SecondPt = new Point3d(V.X, V.Y, V.Z);//only for the second pt option
                    FirstPt=startP.Subtract(V.Convert2d(pn));
                    _normal = Normalvec;
                    bSecondPt = bSecond;
                    El = Elev;

                    if (bSecondPt)
                    {
                        Vector2d Vmid = Firstderiv.Convert2d(pn);
                        midPt = new Point2d(Vmid.X, Vmid.Y);
                    }
                    else
                    {
                        S2 = Util.MyMath.EndSlope(FirstPt, startP);
                    }
                }


                protected override SamplerStatus Sampler(JigPrompts prompts)
                {

                    JigPromptPointOptions jigOpts = new JigPromptPointOptions();
                    jigOpts.UserInputControls = (UserInputControls.Accept3dCoordinates) |
                    UserInputControls.NullResponseAccepted;
                    if (Vcnt > 1)
                    {
                        jigOpts.SetMessageAndKeywords(
                        "\nSpecify next point or [Angle/Close/Line/Second pt/Undo]:",
                        "Angle Close Line Second Undo");
                    }
                    else
                    {
                        jigOpts.SetMessageAndKeywords(
                        "\nSpecify next point or [Angle/Line/Second pt/Undo]:",
                        "Angle Line Second Undo");
                    }

                    jigOpts.BasePoint = BasePt;

                    if (bSecondPt)
                    {
                        jigOpts.Message = "\nSpecify end point of arc:";
                        jigOpts.BasePoint = SecondPt;
                    }

                    jigOpts.UseBasePoint = true;
                    dres = prompts.AcquirePoint(jigOpts);

                    if (dres.Status == PromptStatus.None)
                    {
                        return SamplerStatus.Cancel;
                    }

                    switch (dres.StringResult)
                    {
                        case "Angle":
                            //Todo
                            break;

                        case "Line":
                            return SamplerStatus.OK;

                    }


                    Point2d endPointTemp = dres.Value.Convert2d(pn);

                    if (endPointTemp != endP)
                    {
                        endP = endPointTemp;
                        if (bSecondPt)
                        {
                            endP3d = dres.Value;
                        }
                    }
                    else
                        return SamplerStatus.NoChange;

                    if (dres.Status == PromptStatus.Cancel)
                        return SamplerStatus.Cancel;
                    else
                        return SamplerStatus.OK;

                }//End sampler



                protected override bool Update()
                {
                    try
                    {

                        Point2d Cen;
                        if (bSecondPt)
                        {
                            Cen3d = Util.MyMath.CenterFrom3Pts(BasePt, endP3d, SecondPt);
                            Cen = Cen3d.Convert2d(pn);
                            i = Util.MyMath.isLeft(startP, endP, midPt);

                        }
                        else
                        {
                            Util.MyMath.Slope S1 = Util.MyMath.Bisector(startP, endP);
                            Cen = Util.MyMath.PointFromSlopes(S1, S2);
                            Cen3d = new Point3d(pn, Cen);
                            Cen3d= Cen3d.Add(_normal.MultiplyBy(El));
                           
                            //Cen3d = new Point3d( Cen.X,Cen.Y,0);
                       
                            i = Util.MyMath.isLeft(FirstPt, endP, startP);
                        }
                        double Rad = Cen.GetDistanceTo(startP);


                        if (i == 1)
                        {
                            sAng = Util.MyMath.AngFromX(Cen, endP);
                            eAng = Util.MyMath.AngFromX(Cen, startP);
                        }
                        else if (i == -1)
                        {
                            sAng = Util.MyMath.AngFromX(Cen, startP);
                            eAng = Util.MyMath.AngFromX(Cen, endP);
                        }
                        else
                        {
                            sAng = Util.MyMath.AngFromX(Cen, startP);
                            eAng = Util.MyMath.AngFromX(Cen, endP);
                            i = -1;
                        }

                        ((Arc)Entity).StartAngle = sAng;
                        ((Arc)Entity).EndAngle = eAng;
                        ((Arc)Entity).Center = Cen3d;
                        ((Arc)Entity).Radius = Rad;
                        ((Arc)Entity).Normal = _normal;

                    }
                    catch (System.Exception)
                    {
                        return false;
                    }

                    return true;

                }//End Update



                public PromptPointResult Res()
                {
                    return dres;
                }


                public int MinusPlus()
                {
                    return -i;
                }


                public Entity GetEntity()
                {
                    return Entity;
                }

            }// class PolyArcJig






            #region Command Declarations

            [CommandMethod("DrawPline")]
            public void PlineDraw()
            {
                int iVertex = 0;
                Document doc = acadApp.DocumentManager.MdiActiveDocument;
                Database db = doc.Database;
                Editor ed = doc.Editor;
                bool makepline = true, bCurve = false;
                Polyline oPline = new Polyline(3);
                oPline.SetDatabaseDefaults();
                PromptPointResult Res2 = null;
                ObjectId id = ObjectId.Null;
                double Bulge = 0;

                PolyArcJig jig ;
                Transaction tr=null;
                Matrix3d ucs = ed.CurrentUserCoordinateSystem;
                Vector3d Norm = new Vector3d(0, 0, 1).TransformBy(ucs);
                Plane pn = new Plane(new Point3d(0, 0, 0), Norm);
                Plane pn2 = new Plane(ucs.CoordinateSystem3d.Origin, Norm);
                double Elev=-pn2.Coefficients.D;
                oPline.Elevation = Elev;
                oPline.Normal = Norm;
                PromptPointResult Res1 = ed.GetPoint("\nSpecify start point:");
                if (Res1.Status != PromptStatus.OK) return;

                Point3d BasePt = Res1.Value;
                //Base point needs to stay in ucs
                Point2d P = Res1.Value.TransformBy(ucs).Convert2d(pn);
                oPline.AddVertexAt(0, P, 0, 0, 0);

                PromptPointOptions PPO = new PromptPointOptions("\nSpecify next point or [Arc]:", "Arc");
                PPO.UseBasePoint = true;
                PPO.UseDashedLine = true;
                PPO.AllowNone = true;

                while (Res1.Status == PromptStatus.OK || Res1.Status == PromptStatus.Keyword)
                {
                    try    //add verticies
                    {
                        using (tr = db.TransactionManager.StartTransaction())
                        {
                            PPO.BasePoint = BasePt;
                            if (bCurve) goto Skip; //we already have a picked point
                            if (iVertex > 1)
                            {
                                PPO.SetMessageAndKeywords(
                                   "\nSpecify next point or [Arc/Close/Undo]:", "Arc Close Undo");
                            }
                        LineSkip:
                            Res2 = ed.GetPoint(PPO);
                        Skip:

                            if (Res2.Status == PromptStatus.Cancel) return;
                            if (Res2.Status == PromptStatus.None) return;


                            if (Res2.StringResult == "Arc" || bCurve)
                            {
                                if (iVertex == 0)
                                {
                                    double lastAngle = (double)acadApp.GetSystemVariable("LASTANGLE");
                                    Vector3d V = new Vector3d(1, Math.Tan(lastAngle), 0);
                                    Point3d D = Res1.Value.TransformBy(ucs).Subtract(V);
                                    jig = new PolyArcJig(Norm, iVertex, Res1.Value.TransformBy(ucs),
                                        D.GetAsVector(), pn, Elev, false);
                                }
                                else
                                {
                                    jig = new PolyArcJig(Norm, iVertex,
                                         oPline.GetPoint3dAt(iVertex),
                                        oPline.GetFirstDerivative(iVertex), pn, Elev, false);
                                   
                                }

                                if (ed.Drag(jig).Status == PromptStatus.Cancel)
                                    return;
                                else
                                    Res2 = jig.Res();
                                if (Res2.Status == PromptStatus.None) return;
                                if (Res2.Status == PromptStatus.Keyword)
                                {
                                    switch (Res2.StringResult)
                                    {
                                        case "Line":
                                            bCurve = false;
                                            Bulge = 0;
                                            goto LineSkip;

                                        case "Second":
                                            PromptPointResult SecondPtres = ed.GetPoint
                                                    ("\nPick the second point:");
                                            if (SecondPtres.Status == PromptStatus.Cancel)
                                                return;
                                            if (SecondPtres.Status == PromptStatus.OK)
                                            {
                                                Point3d P3d = SecondPtres.Value;
                                                SecondPtres = null;
                                                jig = new PolyArcJig(Norm, iVertex, Res1.Value,
                                                    P3d.GetAsVector(), pn, Elev, true);
                                                //new Vector3d(P3d.X, P3d.Y, P3d.Z), pn, true);
                                                if (ed.Drag(jig).Status == PromptStatus.OK)
                                                    Res2 = jig.Res();

                                                if (Res2.Status == PromptStatus.Cancel)
                                                    return;

                                            }
                                            break;
                                    }

                                }


                                if (Res2.Status == PromptStatus.OK)
                                {
                                    Arc oArc = (Arc)jig.GetEntity();
                                    Bulge = Math.Tan(oArc.TotalAngle / 4);
                                    Bulge = Bulge * (int)jig.MinusPlus();
                                    bCurve = true;
                                }
                            } //End "Arc" || bCurve


                            if (Res2.StringResult == "Close")
                            {
                                oPline = (Polyline)tr.GetObject(id, OpenMode.ForWrite);
                                oPline.Closed = true;
                                tr.Commit();
                                tr.Dispose();
                                return;
                            }

                            else if (Res2.StringResult == "Undo")
                            {
                                oPline = (Polyline)tr.GetObject(id, OpenMode.ForWrite);

                                if (oPline.NumberOfVertices > 1)
                                {
                                    bCurve = oPline.GetBulgeAt(iVertex - 1) != 0;
                                    oPline.RemoveVertexAt(iVertex);
                                    tr.Commit();
                                    iVertex = iVertex - 2;
                                    BasePt = oPline.GetPoint3dAt(iVertex + 1).TransformBy(ucs.Inverse());
                                }
                                else
                                {
                                    iVertex = iVertex - 1;
                                }
                                goto Undone;
                            }

                            // Points from jig are already in wcs
                            if (bCurve)
                            {
                               P = Res2.Value.Convert2d(pn);
                            }
                            else
                            {
                                P = Res2.Value.TransformBy(ucs).Convert2d(pn);
                            }

                            if (makepline)
                            {
                                oPline.AddVertexAt(1, P, Bulge, 0, 0);
                                oPline.SetBulgeAt(0, Bulge);
                                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                                btr.AppendEntity(oPline);
                                tr.AddNewlyCreatedDBObject(oPline, true);
                                tr.Commit();
                                id = oPline.ObjectId;
                                makepline = false;
                            }
                            else
                            {
                                oPline = (Polyline)tr.GetObject(id, OpenMode.ForWrite);
                                oPline.AddVertexAt(iVertex + 1, P, Bulge, 0, 0);
                                oPline.SetBulgeAt(iVertex, Bulge);
                                tr.Commit();
                            }


                            BasePt = Res2.Value;
                        Undone:

                            iVertex++;

                            Res1 = Res2;
                        }
                    }


                    catch (System.Exception ex)
                    {
                        ed.WriteMessage("\nError: " + ex.Message);
                        tr.Abort();
                    }
                    finally
                    {
                        if (tr != null) tr.Dispose();
                    }

                }
            }//End PlineDraw


            #endregion


        }
    }




    }


Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #18 on: December 20, 2007, 09:47:32 AM »
And the helper section (paste below the other code)
Code: [Select]
//Helper section
namespace Util
{



    class MyMath
    {

        public const int Horizontal = 0;
        public const int Vertical = 1;
        public const int Sloped = 2;



        public static int isLeft(Point2d Startpoint, Point2d Endpoint, Point2d P)
        {
            return isLeftMath(Startpoint, Endpoint, P);
        }


        public static int isLeft(Point2d Startpoint, Point2d Endpoint, Point3d P)
        {
            Point2d Pt = new Point2d(P.X, P.Y);
            return isLeftMath(Startpoint, Endpoint, Pt);
        }


        public static int isLeft(Point3d Startpoint, Point3d Endpoint, Point3d P)
        {
            Point2d Spt = new Point2d(Startpoint.X, Startpoint.Y);
            Point2d Ept = new Point2d(Endpoint.X, Endpoint.Y);
            Point2d Pt = new Point2d(P.X, P.Y);
            return isLeftMath(Spt, Ept, Pt);
        }

        public static int isLeftMath(Point2d Startpoint, Point2d Endpoint, Point2d P)
        {
            double Ans = ((Endpoint.X - Startpoint.X) * (P.Y - Startpoint.Y) -
              (P.X - Startpoint.X) * (Endpoint.Y - Startpoint.Y));
            if (Math.Abs(Ans) < 1.0e-8)
            { return 0; } //P is on the line
            else
            {
                if (Ans > 0)
                { return 1; } //P is left of the line (CW)
                else
                { return -1; } //P is right of the line (CCW)
            }
        }
        //End is left




        static public Point3d CenterFrom3Pts(Point3d P1, Point3d P2, Point3d P3)
        {
            //jheathc   http://discussion.autodesk.com/thread.jspa?messageID=406712

            double X1 = P1.X; double Y1 = P1.Y; double Z1 = P1.Z;
            double xba = P2.X - X1;
            double yba = P2.Y - Y1;
            double zba = P2.Z - Z1;
            double xca = P3.X - X1;
            double yca = P3.Y - Y1;
            double zca = P3.Z - Z1;

            // Calculate the squares of the lengths of the edges incident to x1-y1-Z1

            double balength = (xba * xba) + (yba * yba) + (zba * zba);
            double calength = (xca * xca) + (yca * yca) + (zca * zca);
            // Calculate the cross product of these edges. Take our chances with Intel
            //floating-point roundoff.

            double xcrossbc = (yba * zca) - (yca * zba);
            double ycrossbc = (zba * xca) - (zca * xba);
            double zcrossbc = (xba * yca) - (xca * yba);

            // Calculate the denominator of the formulae.
            double denominator = 0.5 / ((xcrossbc * xcrossbc) + (ycrossbc * ycrossbc) + (zcrossbc * zcrossbc));

            // Calculate offset from x1-y1-Z1 of the circumcenter.

            double xcirca = ((((balength * yca) - (calength * yba)) * zcrossbc) - (((balength * zca)
                     - (calength * zba)) * ycrossbc)) * denominator;
            double ycirca = ((((balength * zca) - (calength * zba)) * xcrossbc) - (((balength * xca)
                    - (calength * xba)) * zcrossbc)) * denominator;
            double zcirca = ((((balength * xca) - (calength * xba)) * ycrossbc) - (((balength * yca)
                    - (calength * yba)) * xcrossbc)) * denominator;
            // Calculate the absolute coordinates of the circumcircle center.
            Point3d Center = new Point3d(xcirca + X1, ycirca + Y1, zcirca + Z1);

            return Center;

        }
        //End CenterFrom3Pts



        public class Slope
        {
            private double Orig;
            private double dX;
            private double dY;
            private double dm;
            private int intSlopeType;
            public double OrigY
            {
                get { return Orig; }
                set { Orig = value; }
            }
            public double X
            {
                get { return dX; }
                set { dX = value; }
            }
            public double Y
            {
                get { return dY; }
                set { dY = value; }
            }
            public double m
            {
                get { return dm; }
                set { dm = value; }
            }
            public int SlopeType
            {
                get { return intSlopeType; }
                set { intSlopeType = value; }
            }

        }


        public static bool Rd(double num1, double num2)
        {
            //if (Math.Abs(num1 - num2) < 1.0e-8)
            double dRet = num1 - num2;
            //bool B=false;
            if (Math.Abs(dRet) < 0.00000001)
            {
                return true;
            }
            return false;
        }



        public static Slope EndSlope(Point2d P1, Point2d P2)
        {
            return EndSlopeMath(P1, P2);
        }

        public static Slope EndSlope(Point3d P1, Point3d P2)
        {
            Point2d P2d1 = new Point2d(P1.X, P1.Y);
            Point2d P2d2 = new Point2d(P2.X, P2.Y);
            return EndSlopeMath(P2d1, P2d2);
        }

        public static Slope EndSlopeMath(Point2d P1, Point2d P2)
        //Pass dSlope and OrigY as empty and they will be given values as they are ByRef
        {
            double deltaX = P2.X - P1.X;
            double deltaY = P2.Y - P1.Y;
            Slope slope = new Slope();

            if (Math.Abs(deltaY) < 1.0e-8) { deltaY = 0; }
            if (Math.Abs(deltaX) < 1.0e-8) { deltaX = 0; }

            if (deltaY == 0)    //Line is horizontal
            //bisector is vertical
            {
                slope.X = P2.X;
                slope.SlopeType = Vertical;

            }
            else if (deltaX == 0) //Line is vertical
            //bisector is horizontal
            {
                slope.Y = P2.Y;
                slope.SlopeType = Horizontal;
            }
            else
            {
                //m = DeltaY / DeltaX
                double dSlope = -deltaX / deltaY;
                slope.m = dSlope;
                slope.OrigY = P2.Y - (dSlope * P2.X);
                slope.SlopeType = Sloped;
            }

            return slope;
        }



        public static Slope Bisector(Point2d P1, Point2d P2)
        {
            return BisectorMath(P1, P2);
        }

        public static Slope Bisector(Point3d P1, Point3d P2)
        {
            Point2d P2d1 = new Point2d(P1.X, P1.Y);
            Point2d P2d2 = new Point2d(P2.X, P2.Y);
            return BisectorMath(P2d1, P2d2);
        }


        public static Slope BisectorMath(Point2d P1, Point2d P2)
        //Pass dSlope and OrigY as empty and they will be given values as they are ByRef
        {
            double deltaX = P2.X - P1.X;
            double deltaY = P2.Y - P1.Y;

            Slope slope = new Slope();
            //cSlope.Capacity = 3;       
            if (Math.Abs(deltaY) < 1.0e-8) { deltaY = 0; }
            if (Math.Abs(deltaX) < 1.0e-8) { deltaX = 0; }
            Point3d MidP = MidPoint(P1, P2);

            if (deltaY == 0)    //Line is horizontal
            //bisector is vertical
            {
                slope.X = MidP.X;
                slope.SlopeType = Vertical;

            }
            else if (deltaX == 0) //Line is vertical
            //bisector is horizontal
            {
                slope.Y = MidP.Y;
                slope.SlopeType = Horizontal;
            }
            else
            {
                //m = DeltaY / DeltaX
                double dSlope = -deltaX / deltaY;
                slope.m = dSlope;
                slope.OrigY = MidP.Y - (dSlope * MidP.X);
                slope.SlopeType = Sloped;
            }

            return slope;
        }



        public static Point2d PointFromSlopes(Slope S1, Slope S2)
        {
            double X, Y;
            int S1Slope = S1.SlopeType;
            int S2Slope = S2.SlopeType;

            if (S1Slope == Horizontal)
            {
                Y = S1.Y;
                if (S2Slope == Horizontal)
                {
                    return new Point2d(null); //Lines are paralell
                }
                else if (S2Slope == Vertical)
                {
                    X = S2.X;
                }
                else
                {
                    X = (Y - S2.OrigY) / S2.m;
                }
            }
            else if (S1Slope == Vertical)
            {
                X = S1.X;
                if (S2Slope == Vertical)
                {
                    return new Point2d(null); //Lines are paralell
                }

                else if (S2Slope == Horizontal)
                    Y = S2.Y;
                else
                    Y = (S2.m * X) + S2.OrigY;
            }
            else
            {
                if (S1.m == S2.m)  //3 pts are in line
                {
                    return new Point2d(null); //Lines are paralell
                }
                else if (S2Slope == Horizontal)
                {
                    Y = S2.Y;
                    X = (Y - S1.OrigY) / S1.m;
                }
                else if (S2Slope == Vertical)
                {
                    X = S2.X;
                    Y = (S1.m * X) + S1.OrigY;
                }
                else
                {
                    //y=mx+c       m1X1+c1=m2X2+c2
                    X = (S2.OrigY - S1.OrigY) / (S1.m - S2.m);
                    Y = (S1.m * X) + S1.OrigY;
                }
            }
            return new Point2d(X, Y);

        }  //PointFromSlopes





        static public Point3d MidPoint(Point3d P1, Point3d P2)
        {
            double x, y, z;
            x = (P1.X + P2.X) / 2;
            y = (P1.Y + P2.Y) / 2;
            z = (P1.Z + P2.Z) / 2;
            return new Point3d(x, y, z);
        }


        static public Point3d MidPoint(Point2d P1, Point2d P2)
        {
            double x, y, z;
            x = (P1.X + P2.X) / 2;
            y = (P1.Y + P2.Y) / 2;
            z = 0;
            return new Point3d(x, y, z);
        }


        static public double AngFromX(Point3d P1, Point3d P2)
        {
            Point2d N1 = new Point2d(P1.X, P1.Y);
            Point2d N2 = new Point2d(P2.X, P2.Y);
            return XAngle(N1, N2);
        }
        static public double AngFromX(Point2d P1, Point2d P2)
        { return XAngle(P1, P2); }

        static public double AngFromX(Point3d P1)
        {
            Point2d N1 = new Point2d(P1.X, P1.Y);
            Point2d N2 = new Point2d(0, 0);
            return XAngle(N1, N2);
        }

        static public double AngFromX(Point2d P1)
        {
            Point2d N1 = new Point2d(P1.X, P1.Y);
            Point2d N2 = new Point2d(0, 0);
            return XAngle(N1, N2);
        }

        static public double AngFromX(Vector3d V)
        {
            Point2d N1 = new Point2d(V.X, V.Y);
            Point2d N2 = new Point2d(0, 0);
            return XAngle(N1, N2);
        }

        static private double XAngle(Point2d P1, Point2d P2)
        {
            double dAng = 0;
            double dX = P2.X - P1.X;
            double dY = P2.Y - P1.Y;
            double pi = Math.PI;
            if (Math.Abs(dY) < 1.0e-8) { dY = 0; }
            if (Math.Abs(dX) < 1.0e-8) { dX = 0; }

            if (dY == 0)//Line is horizontal
            {
                if (dX == 0) goto Skip;

                if (dX > 0) dAng = 0;
                else dAng = pi; //180
            }
            else if (dX == 0) //Line is vertical
            {
                if (dY > 0) dAng = 0.5 * pi; //90
                else dAng = 1.5 * pi; //270
            }
            else
            {
                dAng = Math.Atan(dY / dX);

                if (dAng < 0)  //90->270
                {
                    if (dX < 0) //90->270
                        dAng = pi + dAng; //90->180
                    else //270->360
                        dAng = 2 * pi + dAng;
                }
                else
                {
                    if (dX < 0 && dY < 0) //180->270
                        dAng = pi + dAng;
                }
            }
            return dAng;
        Skip: return 0;

        }


    }


 }

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #19 on: December 21, 2007, 11:17:05 AM »
I'ld appreciate any feedback on cleaning this cod (It still needs the e to make it code) up a bit as I haven't the experience to code with efficiency.
 E.g.  every call for a new point is started with-
using (tr = db.TransactionManager.StartTransaction())
is that heavy on the overhead or doesn't it matter?

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Pick points to 2dpoints.
« Reply #20 on: December 26, 2007, 02:04:37 PM »
Here's a little more on picking points.
The issue comes up in making entities using user provided pickpoints.
This example is a snip from an arc jig.
In autocad the normal for a new object is the normal of the current ucs.
So the plane the new object will be on will use the ucs's normal.
However the origin (Akin to elevation) of that plane needs to reflect the z position of the first pick.
Do this by adding a vector to the ucs origin.
Since we don't know if any further points are on the plane (If anyone knows how to use .ison please post it) we can now .ClosestPointTo to convert the picked point to our plane. Note that this has nothing to do with viewdirection, it merely follows the why cad uses user provided points. I hope the code below explains this method ok

Code: [Select]
          PromptPointOptions opts = new PromptPointOptions("\n Specify start point of arc:");
                PromptPointResult res = ed.GetPoint(opts);

                // Calulate our normal vector...
                Vector3d NormalVec = new Vector3d(0, 0, 1).TransformBy(ucs);
                //Convert the ucs pickpoint to world
                Point3d pickPt = res.Value.TransformBy(ucs);
                //The plane we want is the same as the ucs but needs a new
                //origin to express the Z value of the first picked point
                bool OffZ=(Math.Abs(res.Value.Z) > 0.000001);
                if (OffZ) Orig = Orig.Add(NormalVec.MultiplyBy(res.Value.Z));

                Plane Pn = new Plane(Orig, NormalVec);
                if (OffZ)
                    //Use the inverse matrix to convert the base point back to ucs
                    BasePt = Pn.ClosestPointTo(pickPt).TransformBy(ucs.Inverse());
                else
                    BasePt = res.Value;

                opts.Message="\nsecond point of arc:";           
                opts.BasePoint = BasePt;
                opts.UseBasePoint = true;

                res = ed.GetPoint(opts);
                Point3d pickPt2 = res.Value.TransformBy(ucs);
                //Now use closestpoint to put the second point on the same plane
                pickPt2 = Pn.ClosestPointTo(pickPt2);