 # LISP to Math formula / Ruby code

http://www.lee-mac.com/bulgeconversion.html#arcbulge

Hi there, I’m a ruby developer and starting to be sketchup developer. I was looking for some formula for my bulge calculation and I stumble upon this LISP formula that could help me but unfortunately I don’t have any LISP experience and couldn’t understand it. Could someone help me translate this?

My attempt at translating this LISP function is below in post 5

Let us say that this topic would be a follow on from this one …

Yes, thanks it actually does apparently the formula that ive used previously returns unexpected behavior (arcs are rotating in different direction) but the bulge value is correct

Did you take into account the direction that the ArcCurve’s `normal` vector was pointing ?

The “sort of” translation to SketchUp Ruby is …

``````# Given a SketchUp ArcCurve object, returns the arc's start point, it's bulge
# and it's end point.
# @param arc_curve [Sketchup::ArcCurve]
# @return [Array<Geom::Point3d, Float, Geom::Point3d>]
def arc_to_bulge( arc_curve )
pi = Math::PI
c  = arc_curve.center
# Convert angles from radions to degrees:
#
start_point = arc_curve.first_edge.start.position
end_point   = arc_curve.last_edge.end.position
#
# Define a Lambda (ie, an anonymous function) ...
func = ->(a) { Math.sin(a) / Math.cos(a) }
bulge = func.call(
# ... and immediately call the lambda where the argument is:
(pi + pi + (a2 - a1)).remainder(pi + pi) / 4.0
)
return start_point, bulge, end_point
end
``````

I say “sort_of” because I did not recreate AutoLISP’s `polar` function.

NOTE: I did not examine the function (method) for correctness. The example LISP function most likely relies upon assumptions in the AutoCAD geometric model.

For example, what is the assumed angular datum (vector) for the angles and does it matter if it differs in the SketchUp geometric model ?

Also, in SketchUp, a developer can assign whatever angular datum (vector) they wish as the 2nd argument to `Sketchup::Entities#add_arc`, but it is usually set to `X_AXIS`.

However, if it is set differently, then both the getter methods `Skethcup::ArcCurve#start_angle` and `Skethcup::ArcCurve#start_angle` return values relative to the arcurve’s `Skethcup::ArcCurve#xaxis` vector.

After spending some time reading up on chords, sagitta, unit circle, bulge, etc., it seems the following would be the simplest …

``````def arc_to_bulge( arc_curve )
ai = a2 - a1 # included angle (radians)
bulge = Math.tan(ai/4)
start_point = arc_curve.first_edge.start.position
end_point   = arc_curve.last_edge.end.position
return start_point, bulge, end_point
end
``````

The radius (`r`) bisecting the chord and arc forms two equal angles `θ` (theta) and from this we have the half chord equal to …

``````  hc = r * Math.sin(θ)
``````

The sagitta `s` is equal to …

``````  s = r * (1 - Math.cos(θ))
``````

I’ve verified that the sagitta / half chord ratio equals the tangent of one-quarter of the arc’s included angle:

``````s / hc == Math.tan(ai/4)
``````

NOTE: I get a different result for bulge with the translated LISP function mentioned above.

``````def arc_to_bulge( arc_curve )
ai = a2 - a1 # included angle (radians)
bulge = Math.tan(ai/4)
start_point = arc_curve.first_edge.start.position
end_point   = arc_curve.last_edge.end.position
return start_point, bulge, end_point
end
``````

Thanks I think this is much simpler than I have which is getting the included angle from the vectors from the center to the `start_pt` and `end_pt` then subtracting `Math::PI * 2` if its the a major arc. But I’m still encountering the unexpected rotating of the drawing

``````Did you take into account the direction that the ArcCurve’s normal vector was pointing ?
``````

Are you referring to the vector of the actual bulge? `center_pt to center of the arc line`?

No, I’m referring to the method `arc_curve.normal` `#=> vector of the arc's normal`
It will point forwards or backwards with respect to the arc and tells you which way the arc is “facing”.
Basically it also defines the plane of the arc as given any of the arc’s vertices and the normal vector you define a plane. The normal vector is perpendicular to the any geometric object’s plane. (See the explanation in the overview of the `Geom` module.)

Thanks @DanRathbun
Marking this as a solution since it solves the question that I ask and together with the clockwise direction formula it now works.

1 Like