- Forums Home
- >
- Revit Products Community
- >
- Revit API Forum
- >
- Re: Create a Curve when only the Start Point, End Point & Radius is Known

Community

Revit API Forum

Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

This page has been translated for your convenience with an automatic translation service. This is not an official translation and may contain errors and inaccurate translations. Autodesk does not warrant, either expressly or implied, the accuracy, reliability or completeness of the information translated by the machine translation service and will not be liable for damages or losses caused by the trust placed in the translation service.
Translate

11 REPLIES 11

SOLVED
Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

Message 1 of 12

Anonymous

4804 Views, 11 Replies

10-23-2013
06:39 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

10-23-2013
06:39 PM

Hello

I am attempting to create a Curve (Elipse, Arc, CylindricalHelix, doesn't really matter). But I only know the following properties of the curve:

- The start point (XYZ) of the curve
- The end point (XYZ) of the curve
- The radius of the curve

There aren't any functions that can create an Arc using this information AFAIK. There are only the following functions:

- Arc Create(XYZ end0, XYZ end1, XYZ pointOnArc)
- Arc Create(Plane plane, double radius, double startAngle, double endAngle)
- Arc Create(XYZ center, double radius, double startAngle, double endAngle, XYZ xAxis, XYZ yAxis)

**Do you know how I could create an Arc (or Elipse, CylindricalHelix) using the above functions and the information I know about the arc (start, end and radius)?**

I've tried creating an Arc using the first function ** Arc Create(XYZ end0, XYZ end1, XYZ pointOnArc)** and then setting the Arcs radius property after but it turns out that an Arcs radius property is read only so this doesn't work.

Any advice or suggestions on how I could produce my arc in the Revit APIT would be extremely appreciated.

Solved! Go to Solution.

11 REPLIES 11

Message 2 of 12

Anonymous

in reply to:
Anonymous

10-24-2013
03:40 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

10-24-2013
03:40 AM

Technically speaking, 2 points and a radius are not enough to define a unique arc as there are up to 4 possible arcs that will fit for any plane of reference. Test this yourself by drawing 2 circles of the same size that overlap each other and then draw a line between the 2 intersecting points. Each side of the line will contain 2 arcs that have the same end points and radius.

You can get away with it if you firstly adopt the convention that all arcs are to be drawn in the same direction from start to end (say, anticlockwise) when looking at them in the negative z direction of the target plane and secondly that you always want either the arc with included angle of less than or equal to 180 degrees or the larger arc of over 180°.

That aside, your best option is to calculate a point that lies on the arc and use the 3 points method that you have already used, but this time you will be giving it the correct 3rd point and there will be no need to attempt changing the radius afterwards. We will use the anti-clockwise convention as that is what Revit also uses, we will also assume that the smaller arc is desired.

Here is a little bit of code I just whipped up for you, I have done some minimal testing and it appears to be working fine. I have assumed that you have the 3 following variables already defined and in scope: XYZ end0, XYZ end1 and Double radius. I have also assumed that the arc lies on a plane with a normal vector of XYZ.BasisZ

Double sagitta = radius - Math.Sqrt(Math.Pow(radius, 2.0) - Math.Pow((end1 - end0).GetLength() / 2.0, 2.0)); XYZ midPointOfChord = (end0 + end1) / 2.0; XYZ midPointOfArc = midPointOfChord + Transform.CreateRotation(XYZ.BasisZ, Math.PI / 2.0).OfVector((end0 - end1).Normalize().Multiply(sagitta)); Arc myArc = Arc.Create(end0, end1, midPointOfArc);

If you want the larger arc, simply change the sagitta calculation to be 'radius +' instead of 'radius -'.

If you aren't familiar with the mathematics used to calculate arcs I would suggest heading over to Math Open Reference.

Message 3 of 12

Anonymous

in reply to:
Anonymous

10-24-2013
03:36 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

10-24-2013
03:36 PM

Thanks for your detailed reply 🙂 Its very much appreciated

I am importing data (3d Lines) from another CAD program into Revit. And the data only specifies the arcs start, end and radius. I'll give yor advice a go and see how I go.

Message 4 of 12

Anonymous

in reply to:
Anonymous

10-25-2013
01:29 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

10-25-2013
01:29 AM

No problems, I've just recently been doing some work on line-based families with arc location lines so it was all fresh in my head.

I think you may have some issues acheiving what you are after though, the solution I gave will only really work accurately for 2D data unless you also plug in the correct normal vector (axis) of each arc, basically everywhere that I have used XYZ.BasisZ would need to be replaced with the correct normal vector.

From the data you have it is not possible to determine the correct orientation of the arcs. You will need either a 3rd point on the arc provided for you (which would solve all your problems), or a normal vector of the target plane. Are you sure that there isn't any other information exported for arcs? If not, then the exporter isn't doing a very good job.

A possible solution then could be to see if you can first tesselate the arcs in the source software and then export just the straight line data. You could then rebuild the arcs from the lines as they will give you enough points to define a plane, but the trick would be knowing which lines belong to an arc and which don't. To solve this you could export 2 sets of data, one with tesselation and one without and then mtach the end points found in the tesselated data against the other set to determine whether you need to build an arc or not.

Ok, I'll stop rambling now. Long story short: you need more data!

Edit: I just had the thought that if you have a mixture of arcs and lines and the lines are always tangent to the arcs, you could use the lines each side of an arc to calculate the correct plane.

Message 5 of 12

Anonymous

in reply to:
Anonymous

10-25-2013
03:16 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

10-25-2013
03:16 AM

Yes I have a series of strings (strings of vertices) that I am importing. The string is made of segments (Arc, Line or Point segments). So I have 'the lines each side of the arc' as you say

Heres the data I am importing into Revit (so a segment with a radius of zero means the segment is a Line otherwise its an Arc):

<string_super> <name>22.5</name> <chainage>0</chainage> <breakline>line</breakline> <colour>green</colour> <style>1</style> <time_created>23-Oct-2013 23:45:46</time_created> <time_updated>23-Oct-2013 23:45:46</time_updated> <data_3d> <p>-896.15376506 330.85993976 null</p> <p>-484.5 141.5 null</p> <p>-484.5 141.5 null</p> <p>-232.5 -49.5 null</p> <p>-232.5 -49.5 null</p> <p>-79.22003012 -10.17816265 null</p> </data_3d> <radius_data> 0 0 321.33149289 0 0 0 </radius_data> <major_data> f f f f f f </major_data> </string_super>

Message 6 of 12

Anonymous

in reply to:
Anonymous

10-25-2013
05:53 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

10-25-2013
05:53 AM

Well that data is actually 2D (null z-value) so you should be fine unless you also encounter data with z-values.

I plugged that data into the code above with the addition of some simple line creation stuff and got the following chain of curves. Does this look like the source geometry? Image Link If so then you are good to go

Message 7 of 12

Anonymous

in reply to:
Anonymous

10-06-2014
09:10 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

10-06-2014
09:10 AM

There's a workaround for this issue if you feel like just drawing it out:

Draw a line from your point A to point B.

Draw a circle with a radius equal to the arc you're trying to create.

Move the line such that the centrepoint of the line is at the centrepoint of the circle.

Draw a perpendicular line from each of the endpoints of the line to intersect the edge of the circle.

The part of the circle between those two lines is your desired arc.

It's a bit circuitous, but it works.

Message 8 of 12

03-05-2018
11:07 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

03-05-2018
11:07 PM

Hi Scott!

I try use your code. I translate it to vb. Your code have innacuracy. I fix it.

Dim ar As Arc = Crv Dim radius As Double = ar.Radius Dim sagitta As Double = radius - Math.Sqrt(Math.Pow(radius, 2.0) - Math.Pow((p1 - p0).GetLength() / 2.0, 2.0)) Dim midPointOfChord As XYZ = (p0 + p1) / 2.0 Dim midPointOfArc As XYZ = midPointOfChord + Transform.CreateRotation(XYZ.BasisZ, Math.PI / 2.0).OfVector((p1 - p0).Normalize().Multiply(sagitta)) If Math.Round((midPointOfArc - ar.Center).GetLength, 5) = Math.Round(ar.Radius, 5) Then Return Arc.Create(p0, p1, midPointOfArc) Else midPointOfArc = midPointOfArc - 2 * Transform.CreateRotation(XYZ.BasisZ, Math.PI / 2.0).OfVector((p1 - p0).Normalize().Multiply(sagitta)) Return Arc.Create(p0, p1, midPointOfArc) End If

Message 9 of 12

03-06-2018
12:42 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

03-06-2018
12:42 AM

Dear Andrew,

Your if clause uses the arc center. Where does that come from? We only have radius, start and end point given.

Cheers,

Jeremy

Message 10 of 12

03-06-2018
12:57 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

03-06-2018
12:57 AM

Dear Scott,

Thank you for the very nice solution and explanation.

I added it to The Building Coder samples as well, in C#, like this:

https://github.com/jeremytammik/the_building_coder_samples/compare/2018.0.137.0...2018.0.137.1

/// <summary> /// Create an arc in the XY plane from a given /// start point, end point and radius. /// </summary> public static Arc CreateArc2dFromRadiusStartAndEndPoint( XYZ ps, XYZ pe, double radius, bool largeSagitta = false ) { // https://forums.autodesk.com/t5/revit-api-forum/create-a-curve-when-only-the-start-point-end-point-amp-radius-is/m-p/7830079 XYZ midPointChord = 0.5 * ( ps + pe ); XYZ v = pe - ps; double d = 0.5 * v.GetLength(); // half chord length // Small and large circle sagitta: // http://www.mathopenref.com/sagitta.html double s = largeSagitta ? radius + Math.Sqrt( radius * radius - d * d ) // sagitta large : radius - Math.Sqrt( radius * radius - d * d ); // sagitta small XYZ midPointArc = midPointChord + Transform.CreateRotation( XYZ.BasisZ, 0.5 * Math.PI ) .OfVector( v.Normalize().Multiply( s ) ); return Arc.Create( ps, pe, midPointArc ); }

Cheers,

Jeremy

Message 11 of 12

03-06-2018
05:07 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

03-06-2018
05:07 AM

I edited this discussion and summarised the results for posterity:

Many thanks again to Scott!

Cheers,

Jeremy

Message 12 of 12

03-06-2018
06:00 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report

03-06-2018
06:00 AM

Dear Jeremy!

You are right. I found this topic to solution my task. In my task i have arc and two points on arc 🙂 .

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page