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
  r  = arc_curve.radius
  # Convert angles from radions to degrees:
  a1 = arc_curve.start_angle.radians
  a2 = arc_curve.end_angle.radians
  #
  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 )
  a1 = arc_curve.start_angle # radians
  a2 = arc_curve.end_angle   # radians
  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 )
  a1 = arc_curve.start_angle # radians
  a2 = arc_curve.end_angle   # radians
  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