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?
Solved! Go to Solution.
Solved by Moustafa_K. Go to Solution.
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; }