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

0 Members and 1 Guest are viewing this topic.

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: 8785
  • 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);