Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

XYZ Point VS. Point Parameter

1 REPLY 1
SOLVED
Reply
Message 1 of 2
Moustafa_K
1843 Views, 1 Reply

XYZ Point VS. Point Parameter

Hi!

 

I am having something funny that I want to get through..Basically I want the user selections "DetailedCurves" to form CurveLoop and then cast it as subregionBoundary.

 

I have written the code which works like charm with Arcs and Lines, but when it comes to ellipse, it says can't form a contiguous loop.

 

Here is the code (if the code is confusing I made a briefed explanation to below)

 

 public static CurveLoop convert2loop(IList<CurveElement> Loop)
        {
            CurveLoop crvloop = new CurveLoop();


            crvloop.Append(Loop[0].GeometryCurve as Curve);
            IList<CurveElement> sorted = new List<CurveElement>();
            sorted.Add(Loop[0]);

            for (int I = 0; I <= Loop.Count-sorted.Count; I++)
            {
                ++I;

                foreach (CurveElement cele in Loop)
                {


                    if (sorted.Contains(cele)) continue;    //this to prevent curve duplication

                    


                    if (crvloop.Last().GetEndPoint(1).IsAlmostEqualTo(cele.GeometryCurve.GetEndPoint(0)))
                    {
                        sorted.Add(cele);
                        crvloop.Append(cele.GeometryCurve as Curve);

                    }
                    else if (crvloop.Last().GetEndPoint(1).IsAlmostEqualTo(cele.GeometryCurve.GetEndPoint(1)))
                    {
                        XYZ p = new XYZ(cele.GeometryCurve.GetEndPoint(0).X, cele.GeometryCurve.GetEndPoint(0).Y, 0);
                        XYZ a = new XYZ(cele.GeometryCurve.GetEndPoint(1).X, cele.GeometryCurve.GetEndPoint(1).Y, 0);

                        if (cele.GeometryCurve is Arc)
                        {
                            IList<XYZ> mplist = cele.GeometryCurve.Tessellate();
                            XYZ mp = new XYZ(mplist[1].X, mplist[1].Y, 0);
                            Arc arc = Arc.Create(a, p, mp);
                            crvloop.Append(arc);
                        }
                        
                        else if (cele.GeometryCurve is Ellipse)
                        {
                            Ellipse els = cele.GeometryCurve as Ellipse;
                            
                            Line pl = Line.CreateBound(els.GetEndPoint(0),els.GetEndPoint(1));  //Create this line to get the second point of the perpendicualr line (mid points)
                            Line Perp = Line.CreateBound(pl.Evaluate(0.5, true), els.Evaluate(0.5, true));  //Create virtual perpendicular line to apply the Reference Plan on
                            Plane plane = new Plane(Perp.Direction,new XYZ(0,0,1), pl.Evaluate(0.5,true));  //Create Reference Plane for mirroring

                            Transform trf = Transform.CreateReflection(plane);

                            Ellipse newelp = els.CreateTransformed(trf) as Ellipse;
                                                       
                            IntersectionResult intr = new IntersectionResult();
                            intr = newelp.Project(a);

                            double dis = intr.Parameter;


                            Ellipse final = Ellipse.Create(newelp.Center, newelp.RadiusX, newelp.RadiusY, newelp.XDirection, newelp.YDirection, dis, newelp.GetEndParameter(1));

                            crvloop.Append(final);  //Recorde the corrected Curve in the curveloop
                            
                            sorted.Add(cele);   //recorde the original curve in sorted to prevent Duplication

                         
                        }

                        else if (cele.GeometryCurve is Line)
                        {
                            crvloop.Append(Line.CreateBound(a, p));
                        }

                        sorted.Add(cele);
                    }
                    else continue;


                }
            }
            return crvloop;
        }

 

let me explain a bit:

1- user select detailed curves and path it to the curveloop Method

2- a method gets a 1st curve and plug it in to curveloop ilist

3- get the endpoint (1) of the last curve from the loop 

4- search within selection for another curve containing a point almost equal to the last point in Curveloop.

5-test the type if it is inverted or match the sequence if match then add to curveloop, else...

6- Test the curve if line or arc or Ellipse

7- if Line or Arc redraw the line by inverting the start and end points , then add to curveloop

 

to this stage of the code every thing is fine tested and works perfectly.

 

When it comes to ellipse it is a bit complicated...Why?... Simply because Arc and Line Arguments are XYZ points.

 

 

 

"Curveloop tests the contiguity through the XYZ equality."

 

but Ellipse Argument is not XYZ it is Start and End Parameter :

 Ellipse Create(
	XYZ center,
	double xRadius,
	double yRadius,
	XYZ xAxis,
	XYZ yAxis,
	double startParameter,
	double endParameter
)

 

so i tried the following:

 

8- draw construction lines to get a plan and mirror this Ellipse

9-get the last End point projected on the ellipse and recorde this paramater to draw new Ellipse

 

 

and this returns a fault because the precision of the XYZ Point VS. Point Parameter...

 

the project method gave me these result:

 

 

the XYZ coordinates of the last point in the Curve loop :      a  {(539.141729759, 830.812230539, 0.000000000)} Autodesk.Revit.DB.XYZ

the XYZ coordiantes of the projected point on Ellipse :  intr     {(539.141263004, 830.811193823, 0.000000000)} Autodesk.Revit.DB.XYZ

 

 

the raw Parameter of the point on the inverted Ellipse:                                        dis  -2.1511885290860566 double

the RAW Parameter of the projected point on Ellipse:   newelp.get_EndParameter(0) -2.1511885290860566 double

 

 

from the above results it shows cleary that the same location is 100% equal in a reflex of XYZ, and this is due to the presition of Revit if i remember correctly, it is 1/16 inch.

 

 

I really wish that i clarified every thing...i tried as much as possible. i may explain further if needed..

 

so my question is:

 

How can i image the XYZ of a point to set the parameter of a point? or how can i get this to form a curveloop?

 

 


-----------------------------------------------------
Moustafa Khalil
Tags (2)
1 REPLY 1
Message 2 of 2
Moustafa_K
in reply to: Moustafa_K

i found a good practical answer for this by:

1- getting the start , mid and end point

2- draw 2 arcs and the problem will be solved

 

public static IList<Arc> elps2Arc(CurveElement curve, XYZ startPoint, XYZ endPoint, bool inverted)
        {
            IList<Arc> arcs = new List<Arc>();

            IList<XYZ> points = curve.GeometryCurve.Tessellate();
            XYZ midp1 = points[points.Count / 4];
            XYZ midp2 = points[points.Count - 2];
            Arc arc1 = null;
            Arc arc2 = null;
            if (!inverted)
            {
               arc1 = Arc.Create(startPoint, curve.GeometryCurve.Evaluate(.5, true), midp1);
                arc2 = Arc.Create(curve.GeometryCurve.Evaluate(.5, true), endPoint, midp2);
            }
            else
            {
                arc1 = Arc.Create(startPoint, curve.GeometryCurve.Evaluate(.5, true), midp2);
               arc2 = Arc.Create(curve.GeometryCurve.Evaluate(.5, true), endPoint, midp1);
            }

            arcs.Add(arc1);

            arcs.Add(arc2);

            return arcs;
        } 

 


-----------------------------------------------------
Moustafa Khalil

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community