Arc / Curve Transformation in Ruby

Hi all,

Im 'trying to transform a component by a vector.
Its work perfectly when they aren’t arc in the entities.
On the following image, you can see the result. The initial vertex are represente by a cpoint
the vector by the cline

if I didn’t explode the arc , I have the following result:

I try with

entities.transform_by_vectors entities_to_move, vector

and

transform = Geom::Transformation.new vector
entities.transform_entities(transform,entities_to_move.to_a)

And I have the same result.

I remove the vertices .curve_interior? and its work but I don’t find this very clean.

What is the easiest when to transform an arc ?

Thanks !

Old topic, but in case everyone else runs into this, here is my approach.

I ran into this myself some time ago. SketchUp tries to be smart and smoothly change the whole curve when you move only a single vertex. This makes perfect sense when you actually only want to move one vertex, but if you calculate the positions for all vertices and repeatedly “smoothly” change the curve as a whole, you end up with a very odd result.

My workaround is to explode the curve before moving it. The vertices making up the curve can be cached and the curve restored using Entities#weld after the move is done.

1 Like

Hi thx for your answer
I finally extract cuver from entities to be moved

		greped_arcs = entities_to_move.grep(Sketchup::Vertex).select{|v| v.curve_interior?}
		entities_to_move -= greped_arcs

		entities.transform_by_vectors entities_to_move, vectors
2 Likes

That’s probably an even cleaner solution!

This is perhaps the clearer way of doing it…
Note that to be useful it needs to be written inside its own module, with good error-trapping, and also include a start/commit_operation [undo] block etc

model=Sketchup.active_model
ents=model.active_entities
### work on selected edges only
ss=model.selection
edges=ss.grep(Sketchup::Edge)
vxs=[]
edges.each{|e| vxs << e.vertices }
vxs.flatten!
vxs.uniq!
vxs.dup.each{|v| vxs.delete(v) if v.curve_interior? }
### vxs is now an array of transformable vertices only
### use whatever vector you want...
vec=Geom::Vector3d.new(1.m, 1.m, 0)
tr=Geom::Transformation.translation(vec)
### works with other tranformation types too...
ents.transform_entities(tr, vxs)
### done

Hi TIG, I know you’re a great ruby coder as Eneroth

what do you things about this way to code ?
→ why don’t use map instead of each
→ why don’t use select
→ why they’re no space around = ( variable=value)
( you writhe it fastly or its optimisation or its not important ?)

	model=Sketchup.active_model

	model.start_operation "move edge", true

	ents=model.active_entities

	### work on selected edges only

	ss=model.selection

	edges=ss.grep(Sketchup::Edge)

	vxs=edges.map{|e| e.vertices }
		&.flatten
		&.uniq

	vxs_with_out_curve = vxs.select{|vx| !vx.curve_interior?}

	### vxs is now an array of transformable vertices only

	### use whatever vector you want...

	vec=Geom::Vector3d.new(1.m, 1.m, 0)

	tr=Geom::Transformation.translation(vec)

	### works with other tranformation types too...

	ents.transform_entities(tr, vxs_with_out_curve)

	model.commit_operation

	### done

I managed to simplify it to just a one-liner!

entities_to_move.reject! { |e| e.is_a?(Sketchup::Vertex) && e.curve_interior? }

personally I would argue conventional use of whitespaces and parenthesis do a lot for readability and noise reduction. Sames goes for smart use of Ruby’s built in methods to avoid spelling out low level data juggling that could be expressed in a single word.

Using Rubocop has helped me a lot in writing cleaner and more easily readable code, that better fits into the conventions of the industry.

1 Like

There are many ways to achieve the same result in Ruby.
I wrote the example in a few minutes so I was not careful about formatting, or using the most efficient methods…
I separated it in to parts so that it was perhaps clearer what each step did rather than using some arcane coding tricks which are less clear.
Both map and select are however both good approaches…
There’s no need to separate the variable and its value with spaces around the = sign
However, it can help readability - but using sensible variable names is just as important, as is properly parenthesizing variables that are being passed to a method…

Note that naming the array of vertices to be transformed as vxs_with_out_curve is potentially confusing as only those vertices lying within the curve are ignored - the curve’s end and start vertices are kept in the array, although of course they might also be shared with abutting plain edge vertices [which are simplified in the flatten/uniq steps]

1 Like