Revit API

Posts: 14
Registered: ‎06-18-2009
Message 1 of 2 (187 Views)
Accepted Solution

XYZ Point VS. Point Parameter

187 Views, 1 Replies
02-08-2014 01:21 PM



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>();

            for (int I = 0; I <= Loop.Count-sorted.Count; 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)))
                        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);
                        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));

                    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?



Posts: 14
Registered: ‎06-18-2009
Message 2 of 2 (161 Views)

Re: XYZ Point VS. Point Parameter

02-09-2014 01:32 PM in reply to: mostafa90

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);
                arc1 = Arc.Create(startPoint, curve.GeometryCurve.Evaluate(.5, true), midp2);
               arc2 = Arc.Create(curve.GeometryCurve.Evaluate(.5, true), endPoint, midp1);



            return arcs;


You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community

Revit Exchange Apps

Created by the community for the community, Autodesk Exchange Apps for Revit helps you achieve greater speed, accuracy, and automation from concept to manufacturing.

Connect with Revit