Selected segment != numerical segment

Hello

I am evaluating some array of points by comparing them with segments created from any two of the points
I can subtract a segment from the array, but when I denote that segment by selecting it in the model it doesn’t seem to recognize it, even though it is the same segment.

mod = Sketchup.active_model 
ents = mod.entities 
sel = mod.selection

points = (0..10).collect{|i| Geom::Point3d.new(rand, rand, rand)}
copy = points.clone
ents.add_edges(points)
edges = ents.grep(Sketchup::Edge)
segment = points[2..3]
edge = edges.find{|edge|[edge.start.position, edge.end.position] == segment or 
                        [edge.start.position, edge.end.position] == segment.reverse}
sel.add(edge)
z = copy - segment

segment_selected = [sel[0].start.position, sel[0].end.position]
zz = copy - segment_selected

segment does equal segment_selected
z does not equal zz

I must be making a simple mistake but I can’t figure it out…

P.S

zz = copy - segment_selected.reverse also doesn’t work

Since you are using rand() to generate point coordinates, the possibility exists that your edges intersect and are broken into smaller edges. Ie, 3 or 4 edges (or more) may have vertices at the intersection point which is not in your points array.

One of the basic rules of testing, is use a known “control group”. So, I would avoid the use of rand().


FYI, … Kernel#clone produces a shallow copy. This means that the actual point objects in each array are the same objects.

However, the SketchUp engine will move the vertices depending upon the internal tolerance for points. So, the real coordinates might be slightly different from your original points array members.


Lastly, the Enumerable#grep method is in no way guaranteed to return members in the same order as they were added to the entities collection, as the former is a core Ruby method and the latter is done via the SketchUp API.

Thank you Dan. You are providing exactly the kind of information that I need to understand the workings of Sketchup ( still a long way to go…) I have tried my “test” again with clean non intersecting points and the problem is no longer detected.

About clone, say I have:

edges = ents.add_circle(ORIGIN, Geom::Vector3d.new(0,0,1), 24)
segments = edges.collect{|e| [e.start.position, e.end.position]}

rather than using:

copy = segments.clone

would it be effective, or efficient, to use:

copy = segments.collect{|seg|[Geom::Point3d.new(seg[0].to_a), Geom::Point3d.new(seg[1].to_a)]}

It depends upon what your goal is.

I’m not sure there is any real benefit to decomposing the edges array into an array of two point arrays. I mean basically, an edge is a segment.

# @param edges [Array(SketchUp::Edge)] An array of edge objects.
# @param pt1 [Geom::Point2d] One of the end points.
# @param pt2 [Geom::Point2d] The other end points.
#
# @return [SketchUp::Edge,nil] Returns nil if not found.
def find_edge(edges, pt1, pt2)
  edges.find { |e|
    ( e.start.position == pt1 && e.end.position == pt2 ) ||
    ( e.start.position == pt2 && e.end.position == pt1 )    
  }
end

Thanks again for your helpful tips. I appreciate it. You are very generous.

1 Like