[solved] taking points at intervals from a line
-
Let's call them
p0
andp1
The distance between them...
dis=p0.distance(p1)
Let's assume we want to find a set of points at 1/n steps
step=dis/n
Then process and increment
vec=p0.vector_to(p1) pts=[p0] p=p0.clone (n-1).times{ pt=p.offset(vec, step) pts << pt p=pt.clone } pts << p1
You now have an array 'pts' of all points including the start and end ones and all intermediate ones as required... -
@dan rathbun said:
@kdasilva said:
how can I get 10 Point3d's evenly spread out along this line that I can use as anchors for my text....
Divide the line by 9
<span class="syntaxdefault">arr</span><span class="syntaxkeyword">=[]<br /></span><span class="syntaxcomment"># load array with the txt values in order<br /></span><span class="syntaxdefault">pt </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position<br />vec </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">line<br />num </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> dict</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">size</span><span class="syntaxkeyword">-</span><span class="syntaxdefault">1<br />seg </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> vec</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxkeyword">/</span><span class="syntaxdefault"> num<br />vec</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> seg<br />arr</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_with_index </span><span class="syntaxkeyword">{|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault"> pt</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">offset</span><span class="syntaxkeyword">!(</span><span class="syntaxdefault">vec</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> if i</span><span class="syntaxkeyword">></span><span class="syntaxdefault">0<br /> entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_text</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> arr</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">],</span><span class="syntaxdefault"> pt </span><span class="syntaxkeyword">)<br />}</span><span class="syntaxdefault"> </span>
I am trying my hardest to get this to work, unfortunately I have been unsuccessful thus far.....i put in:
def draw_vision_field vision_field = ["test1", "test2", "test3", "test4", "test5"] pt = $line.start.position puts pt vec = $line.line puts vec num = vision_field.size - 1 puts num seg = vec.length / num puts seg vec.length = seg vision_field.each_with_index {|e,i| pt.offset!(vec) if i > 0 $ents.add_text( vision_field[i], pt ) } end
I just put a test array to print for now. I added the puts in order to try and debug, I am getting this error message regarding the length= function on a vector...also the last number before the word error (the vec.length /num ), weirdly enough is always 0, i removed the /num and it always prints as 2, no matter how long the line is i make)
(-350507.397831", 21906.712364", 0") (-350507.397831", 21906.712364", 0") (0.131501105216966, 0.991316023943281, 0.0) 4 0 Error; #<NoMethodError; undefined method `length=' for [Point3d(-350507, 21906.7, 0), Vector3d(0.131501, 0.991316, 0)];Array> (eval);70;in `draw_vision_field' (eval);55;in `draw_the_line' (eval);28;in `onLButtonDown' (eval);73
also... where does the method each_with_index come from? I can't find it in the sketchup api, and I could only find each_index in the ruby-doc http://www.ruby-doc.org/core/classes/Array.html#M000232
thanks for the help
korbin
-
@kdasilva said:
<snip>
i removed the /num and it always prints as 2, no matter how long the line is i make)
<snip>You don't want to use a line. A line would have infinite length. Anyways, it's just seen as an array ( type "edge.line.class"). So the length of that array is always 2 elements in that array, which defines a line.
You want to use the vector from the edge:
pt1 = edge.start.position pt2 = edge.end.position vec = Geom;;Vector3d.new [(pt2.x-pt1.x), (pt2.y-pt1.y), (pt2.z-pt1.z)] edge_length = vec.length
@kdasilva said:
<snip>
also... where does the method each_with_index come from? I can't find it in the sketchup api, and I could only find each_index in the ruby-doc http://www.ruby-doc.org/core/classes/Array.html#M000232thanks for the help
korbin
The sketchup api just documents, extra ruby Modules/Classes/methods for sketchup. It doesn't document the entire ruby language.
-Kwok
-
In general, interpolating points should be done with
Geom.linear_combination
in your case, to create nb intermediate segments ( so nb+1 points, including first and last one)def intermediate_points(pt1, pt2, nb) lpt = [] for i in 0..nb ratio = 1.0 * i / nb lpt.push Geom.linear_combination(1 - ratio, pt1, ratio, pt2) end lpt end
which you can write in a single line as well
(0..nb).to_a.collect { |i| r = 1.0 * i /nb ; Geom.linear_combination(1-r, pt1, r, pt2) }
Fredo
-
@kyyu said:
You don't want to use a line. A line would have infinite length. Anyways, it's just seen as an array ( type "edge.line.class"). So the length of that array is always 2 elements in that array, which defines a line.
Yes. I am sorry Korbin, meant to use the second element from the line method (got rushed.)
I should have written:
vec = edge.line[1]
notvec = edge.line
Also within a method, you dont need to use a global variable. Pass a reference to the line into the method as an argument. The argument name becomes a local reference (var) inside the method. (Do not get in the habit of using global vars. Its poor and lazy programming.)
<span class="syntaxdefault">def draw_vision_field</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> edge </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> ents </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_entities<br /> vision_field </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[</span><span class="syntaxstring">"test1"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"test2"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"test3"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"test4"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"test5"</span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault"> pt </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position<br /> puts pt<br /> vec </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">line</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">]</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># fixed this <br /></span><span class="syntaxdefault"> vec</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxcomment"># added this<br /></span><span class="syntaxdefault"> puts vec<br /> num </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> vision_field</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">size </span><span class="syntaxkeyword">-</span><span class="syntaxdefault"> 1<br /> puts num<br /> seg </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> vec</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxkeyword">/</span><span class="syntaxdefault"> num<br /> puts seg<br /> vec</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> seg<br /> vision_field</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_with_index </span><span class="syntaxkeyword">{|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault"> pt</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">offset</span><span class="syntaxkeyword">!(</span><span class="syntaxdefault">vec</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> if i </span><span class="syntaxkeyword">></span><span class="syntaxdefault"> 0<br /> ents</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_text</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> vision_field</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">],</span><span class="syntaxdefault"> pt </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> </span><span class="syntaxkeyword">}</span><span class="syntaxdefault"> <br />end<br /></span>
EDIT:
edge.line[1]
returns a unit vector, so we must add a statement to makevec
the length ofedge
. -
@kdasilva said:
how can I get 10 Point3d's evenly spread out along this line that I can use as anchors for my text....
Divide the line by 9
<span class="syntaxdefault">arr</span><span class="syntaxkeyword">=[]<br /></span><span class="syntaxcomment"># load array with the txt values in order<br /></span><span class="syntaxdefault">pt </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">position<br />vec </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">line</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault">vec</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length <br />num </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> dict</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">size</span><span class="syntaxkeyword">-</span><span class="syntaxdefault">1<br />seg </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> vec</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxkeyword">/</span><span class="syntaxdefault"> num<br />vec</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> seg<br />arr</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_with_index </span><span class="syntaxkeyword">{|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault"> pt</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">offset</span><span class="syntaxkeyword">!(</span><span class="syntaxdefault">vec</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> if i</span><span class="syntaxkeyword">></span><span class="syntaxdefault">0<br /> entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_text</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> arr</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">],</span><span class="syntaxdefault"> pt </span><span class="syntaxkeyword">)<br />}</span><span class="syntaxdefault"> </span>
EDIT:
vec = edge.line[1]
wasvec = edge.line
Added:vec.length = edge.length
as edge.line[1] returns a unit vector. -
@kyyu said:
You want to use the vector from the edge:
pt1 = edge.start.position > pt2 = edge.end.position > vec = Geom;;Vector3d.new [(pt2.x-pt1.x), (pt2.y-pt1.y), (pt2.z-pt1.z)] > edge_length = vec.length
This is what I intended, but left off the index to the 2nd element.
edge.line[1]
returns the unit vector for the edge, so:vec = edge.line[1] vec.length = edge.length
-
Wow, thanks for all the help, and that fixed it up no problem.
Dan - I also got rid of all of the global variables...in some cases I used class variables I hope thats not bad coding...changes to a variable in one method needed to be consistent in other methods for some parts in the tool
(your all definitely getting a thank you foot note in my thesis!)
Cheers,
Korbin -
@kdasilva said:
also... where does the method each_with_index come from?
The method
each_with_index()
comes from the special mixin-moduleEnumerable
, which is mixed into many other classes likeString
,Hash
andArray
.On the Docs page for each class, it lists what other modules are "mixed-in" using the
include()
method, so therefore the caption Included.
And for Sketchup use the v 1.8.6 docs:
Core: http://www.ruby-doc.org/core-1.8.6/index.htmlThe Keywords apply to all branches and versions.
Keywords: http://www.ruby-doc.org/docs/keywords/1.9/ -
@kdasilva said:
...in some cases I used class variables I hope thats not bad coding...changes to a variable in one method needed to be consistent in other methods for some parts in the tool
No that's proper programing.. (and what I do,) if the tool instance is a singleton instance (the only instance of the tool class that will be instantiated, which is usually the case,) ... then using class variables is fine.
If it's an instance of a class that will have more than one instance "live" at a time, then instance variables (beginning with only 1
@
,) would be what you want to use. (That way each instance has it's own set of the variables.)You can also use class constants (is place of global constants,) and local variables (in place of global variables.)
-
@tig said:
pt=p.offset(vec, step)
Some help about the second argument \in API there is only one - vector\
Thanks
-
-
point.offset()
returns a new point from 'point', offset as specified BUT
point.offset**!**()
offsets the original 'point', as specified. -
Ah, thanks for all the tips, guys! The line[1] vector will be useful, as long you are after the forward edge direction. I tried to use it yesterday, but couldn't because the polyline direction did matter in my case. And the second argument in .offset(). I didn't realize there was a second argument and was scaling my vector, instead. Actually, I only recently realized you could scale a vector by vector.length= and had been doing it a harder way, before.
-Kwok
Advertisement