Find a Curve's center/radius

1,027 views
Skip to first unread message

Amos

unread,
May 2, 2009, 12:55:11 AM5/2/09
to Google SketchUp Developers - SketchUp Ruby API
Before I "invent my own wheel" to find a Curve's center/radius, does
anyone have some code I can just "require"? Maybe an (open-source)
export plugin that has to handle curves for some file format? (That's
my problem, BTW. I'm trying to export RS274 "G code" for CNC
machinery...)

If not, how about some pointers on how to go about it? (Math is not
one of my strong points...)

My plan so far is something like:
1. Find what plane the curve is in. (Just check the coords of the
first/last points for commonalities; better way?)
2. Find perpendiculars for the first and last Edges that lie in this
plane. (cross product)
3. Find the intersection (if any) of these lines.
4. Etc.

Sound good? Of course, since a curve is just a group of edges, it
isn't necessarily a circular arc like an ArcCurve, but my main concern
is with ArcCurves that have "degenerated" to Curves by being
intersected, split, etc. I can always just put out each edge as a G01
(linear movement), like I do now, when I encounter those "oddballs".

Thanks for reading and/or responding. This group is great!

Chris Fullmer

unread,
May 2, 2009, 9:47:18 PM5/2/09
to Google SketchUp Developers - SketchUp Ruby API
I think the easiest way to do it is to look at each edge in the
supposed curve. Take an edge and its adjoining edge. Get their
vectors. Then do a linear combination of their vectors to find the
vector that goes through their centerpoint. Then look at the next
segment in the curve and do the same. Get the vector that runs
through its center. Then take those 2 vectors and get the point where
the intersect.

You will need to do this for every segment since you have no way of
knowing if you are looking at a true (but degraded) arcCurve or just a
series of connected edges. A degraded arccurve will give the
centerpoint each time you test for the intersection of the 2 vectors.
So as soon as you have a centerpoint that doesn't equal the previous
centerpoint, you'll know that you are into a new ArcCurve or that the
current segments should not be treated as an arc or a circle for the
export.\

Does that make any sense? It does in my mind, but perhaps I didn't
get it out well.. Let me know. I wrote very similar code to this in
a recent script. Its just so buried and integrated into that script
it would be hard to pull out and examine I think. But if you want to
look at it, its in Shape bender

http://www.sketchucation.com/forums/scf/viewtopic.php?f=180&t=18210

Good luck,

Chris

Amos

unread,
May 3, 2009, 7:23:13 PM5/3/09
to Google SketchUp Developers - SketchUp Ruby API
Wow, what a great script! I don't know how I missed that one. Thanks
for sharing it!

I think you were right about my inability to find the right code
inside (is it mainly the code in "get_normals" to which you refer?)
but, your description above seems to have done the trick! :D

Despite Wikipedia and multiple Google searches, I hadn't been able to
wrap my head around the concept of "linear combination." Something I
read said that it's the sum of the products of two or more vectors and
two or more scalars, but I didn't know how to pick the scalars or what
to do with the result.

But, since you suggested it, I decided to make some test code and,
while I still don't know /how/ it works, I'm pretty sure I grasp /
what/ it does and how that can be used. Much simpler than finding
perpendiculars to the edges and it's built in! :D

You even solved the problem I hadn't even started thinking about,
which is finding whether a Curve can still be used as an ArcCurve.

In short, you rock! ;)

Thanks,
Amos

Chris Fullmer

unread,
May 4, 2009, 1:29:11 AM5/4/09
to Google SketchUp Developers - SketchUp Ruby API
Good, glad you found it helpful. I also put together a quick 5 scene
model that hopefully will help visualize what a liner combination is.
click from one scene to the next to see my explanation. And scene 5
is sort of a jumble of text and lines, but hopefully its labeled well
enough to be meaningful. It can be found here

http://chrisfullmer.com/chrisfullmer/forums/linear%20combination.skp

Chris

wehby

unread,
May 5, 2009, 12:46:23 PM5/5/09
to Google SketchUp Developers - SketchUp Ruby API
Chris,
That shape bender looks pretty neat. I took a look at your example SKP
and wanted to ask the following:

In Scene 2, where you have all of the lines perpendicular to the curve
segments, why not just move the perpendicular lines to the midpoint of
each segment? Then the point at which they all intersect would be the
center -- without doing the linear combination.

Take care,
wehby
> > Amos- Hide quoted text -
>
> - Show quoted text -

Chris Fullmer

unread,
May 8, 2009, 2:07:19 AM5/8/09
to Google SketchUp Developers - SketchUp Ruby API
Hey Wehby. Good question. I had to do it that way in shape bender
because of the way it works. It has to know the actual combined
vectors at each end of the segment so that is can accurately locate
all the points in between those vectors.

But I think you're right, it might not be necessary for what he is
writing. My brain is so stuck in Shape Bender mode, I was thinking
the only way to find the center point of arcs would be the linear
combination.

Plus your method is nicer because with mine, the ends of the end
segments are difficult to find the needed vector. But that is a non
issue with your method. Thanks for pointing out the easier road!

Good to see you around John, can we be expecting some more scripts
then????

Chris

TIG

unread,
May 10, 2009, 8:16:27 AM5/10/09
to Google SketchUp Developers - SketchUp Ruby API
See http://code.google.com/apis/sketchup/docs/ourdoc/arccurve.html

# Methods
* center
* end_angle
* normal
* plane
* radius
* start_angle
* xaxis
* yaxis
These give all of the arc properties that you need to export
First get the arc from one of its edges...
arc=edge.curve if edge.curve.typename=="ArcCurve"
A circle is a special case of arc, with equal end and start angles ?
Then...
radius=arc.radius [in inches]
plane=arc.plane
etc...

TIG
Message has been deleted

nobnob

unread,
May 10, 2009, 9:10:34 AM5/10/09
to Google SketchUp Developers - SketchUp Ruby API
My script may help a part of this topic.
This exchanges radius of selected single/multi curve(s).

def niradius
if Sketchup.os_language == "ja"
titietext = "aaaaa"
promptstext = "bbbbb"
Sketchup::set_status_text "ccccc"
else
titietext = "exchange radiuses"
promptstext = "new radius(mm)"
Sketchup::set_status_text "exchange multi radiuses at once."
end
prompts = [promptstext]
values = [50.0]
newradius = UI.inputbox prompts, values, titietext
return if newradius == false
Sketchup.active_model.start_operation titietext
curvelist = []
model = Sketchup.active_model
entities = model.active_entities
model.selection.each do |i|
next unless i.kind_of?(Sketchup::Edge)
curve = i.curve
next if curve==nil
curvelist.push curve unless curvelist.index(curve)
end
curvelist.each do |curve|
oldradius = curve.radius.to_mm
point = curve.center
scale = newradius[0] / oldradius
transf = Geom::Transformation.scaling point, scale
entities.transform_entities transf, curve
end
Sketchup.active_model.commit_operation
end


if( not file_loaded?("niradius.rb") )
if Sketchup.os_language == "ja"
UI.menu("Plugins").add_item("ddddd") { niradius }
else
UI.menu("Plugins").add_item("exchange radiuses") { niradius }
end
end
#--------------------------------------------------------------------------­---
file_loaded("niradius.rb")

Amos

unread,
May 11, 2009, 12:24:38 AM5/11/09
to Google SketchUp Developers - SketchUp Ruby API
On May 10, 7:16 am, TIG <t...@revitrev.org> wrote:
> Seehttp://code.google.com/apis/sketchup/docs/ourdoc/arccurve.html
>
> # Methods
>     * center
>     * end_angle
>     * normal
>     * plane
>     * radius
>     * start_angle
>     * xaxis
>     * yaxis
> These give all of the arc properties that you need to export
> First get the arc from one of its edges...
> arc=edge.curve if edge.curve.typename=="ArcCurve"
> A circle is a special case of arc, with equal end and start angles ?
> Then...
> radius=arc.radius [in inches]
> plane=arc.plane
> etc...
>
> TIG

Thanks TIG, but I had actually already seen that. As I wrote in the
OP:

"Of course, since a curve is just a group of edges, it isn't
necessarily a circular arc like an ArcCurve, but my main concern is
with ArcCurves that have "degenerated" to Curves by being intersected,
split, etc."

I sort of implied that I knew about the properties of ArcCurves, but I
guess I wasn't very clear.

Oh well ;)

Amos

unread,
May 11, 2009, 1:14:12 AM5/11/09
to Google SketchUp Developers - SketchUp Ruby API
Thanks, nobnob,

That looks quite handy, but I'm not sure how it helps with my
problem...

Since it uses the ".radius" method, I assume it will only work with
ArcCurves specifically, and not Curves in general.

I must admit that I haven't tried, but since the docs say that
ArcCurve inherits from Curve and not vice versa, I assumed that
the .radius, .center, etc. methods only worked on the former. Am I
wrong?

I've decided that I'm going to make my exporter only support ArcCurves
and I'll make a separate plugin that can automatically convert Curves
to ArcCurves if they can be, since this seems like a useful function
on its own. Also, there may be a time when, for whatever reason, a CNC
machinist might want a circular curve to be exported as separate
segments, in which case he/she can just "'Splode'n'Weld(TM)" ;)

So far I have code that (somewhat reliably) finds the center of a
"true" Curve and can also (usually) detect when it's just a group of
edges. Next I have to check if the vertices all share the same radius,
since G02/03 codes only support circular arcs (to the best of my
knowledge).

Thanks again to everyone taking an interest in this problem :D
Keep the input coming ;)

-Amos

Chris Fullmer

unread,
May 11, 2009, 3:14:44 PM5/11/09
to Google SketchUp Developers - SketchUp Ruby API
I just wrote a script last night that finds the centerpoint of an
exploded arc.

It does not do very much error checking though. So its is very
possible for it to place a centerpoint on segments that were not an
arc. But I made a video that shows how it works and the code is not
scrambled, so it should be easy enough to look through. I did not
comment it very well, and there might be some variables that are
created that are not actually used. I took a few different approaches
to solve the problem, and I don't know if I cleaned up the unused
portions very well. But feel free to look it over. Its all here:

http://www.sketchucation.com/forums/scf/viewtopic.php?f=180&t=18963

It works using John (Wehby)'s suggestion of find the perpendicular
vectors coming off the segments, moving them to the center of the
segment, then finding where those vectors intersect. Works like a
charm. But again, it does very little error checking on the segments,
so its possible to get false positive results.

Chris
Reply all
Reply to author
Forward
0 new messages