I would like a script to be able to create a staggered edges similar to brickwork formation.
I have written a script that divides the edges and does a raytest to perpendicular edge, my issue at this stage is the script only works for squares/rectangles, how do I get it to work for irregular polygons? any help much appreciated, thank you.
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
# Sorted edges length
e = ent.grep(Sketchup::Edge)
e_sort = e.sort{|a,b|
a.length <=> b.length}
# Vector of the longest edge
vec = e_sort.last.start.position.vector_to e_sort.last.end.position
# Get vector rotation the correct direction
edge = e_sort.last
fa = edge.faces[0]
ang = 90.degrees
ang = -ang if edge.reversed_in?(fa)
# Edge point to rotate vector
ec = edge.bounds.center
# Rotate vector 90 degrees to get a perpendicular vector
vec_trans = Geom::Transformation.rotation(ec, Z_AXIS, ang)
rot = vec.transform!(vec_trans)
# Select the Original vector
vec2 = e_sort.last.start.position.vector_to e_sort.last.end.position
# Cpoint spacing
s = 3000.mm
#Cpoint num
num = vec2.length / s
cpoints = []
# Add Cpoints along edge
(0..num).each { |i|
sp = e_sort.last.start.position.offset(vec2,i*s)
cpoints << sp
#ep = e_sort[1].end.position.offset(vec2,i*s)
cp = ent.add_cpoint(sp)
}
# Add Cpoint at the end pf edge
ent.add_cpoint(e_sort.last.end.position)
cpoints << e_sort.last.end.position
# Raytest each Cpoint to the perpendicular edge
cpoints.each{|cpt|
rayt = mod.raytest(cpt,rot)
pt = rayt[0]
cp2 = ent.add_cpoint(pt)
ent.add_line(cpt,pt)
}
One approach could be to utilize the Geom helper method (which tend to be much faster that trying to compute intersection yourself in pure Ruby.)
For instance, you could take the boundary and use point_in_polygon2D to see if any computed points for the segments you have are outside the bounday, if they are use intersect_line_line to crop?
Thanks for your comment tt_su, I am struggling along with this. The below is the code I have written to divide the face perpendicular to the longest edge. Do you have suggestions for making this more efficient?
def divide_face
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
# select face
face=ent.grep(Sketchup::Face).first
#edges
e = ent.grep(Sketchup::Edge)
# find longest edge
esort = e.sort{|a,b|
a.length <=> b.length
}
edge = esort.last
#longest edge start and end point
p1=edge.start.position
p2=edge.end.position
# vector perpendicular to longest edge
ang = 90.degrees
ang = -ang if edge.reversed_in?(face)
vector = edge.start.position.vector_to edge.end.position
vector_trans = Geom::Transformation.rotation(edge.bounds.center, face.normal, ang)
vector.transform!(vector_trans)
# group face
aent=mod.active_entities
group = aent.add_group(face)
group.name="Boundary"
#scale longest line
edge1=ent.add_line(p1,p2)
point = edge1.bounds.center
scale = 2
tr = Geom::Transformation.scaling(point, scale)
scale=ent.transform_entities(tr,edge1)
s1=edge1.start.position
s2=edge1.end.position
#add perpendicular line
perp=ent.add_line(edge1.bounds.center, edge1.bounds.center.offset(vector))
# add longest edge
longest=ent.add_line(s1,s2)
#line of the longest edge
line=edge.line
# length of perpendicualr edge
len=edge.length
dist=1220.mm
perpl=perp.line
tx=perpl[1].x*dist
ty=perpl[1].y*dist
tz=perpl[1].z*dist
tt1=[tx,ty,tz]
ent.add_cpoint(tt1)
point2=longest.bounds.center
transform = Geom::Transformation.new(point2)
point1 = tt1
point3 = point1.transform(transform)
ent.add_cpoint(point3)
space_line=ent.add_line(point2,point3)
vec2 = point2.vector_to point3
# num of offsets
num=longest.length / dist
# collect offset lines
lines=[]
#offset longest edge by perp vec dist
for i in (0..num)
line1=ent.add_line(longest.start.position.offset([vec2.x*i,vec2.y*i,vec2.z*i]),longest.end.position.offset([vec2.x*i,vec2.y*i,vec2.z*i]))
lines << line1
end
#select lines same direction as perp
parallel_edges=ent.select{|e|e.is_a?(Sketchup::Edge) && e.line[1].samedirection?(perp.start.position.vector_to perp.end.position)}
ent.erase_entities(parallel_edges)
tr_intersect=Geom::Transformation.new()
ent.intersect_with( false, tr_intersect, ent, tr_intersect, true, ent.to_a)
group.explode
del=ent.select{|e|e.is_a?(Sketchup::Edge) && e.faces.length==0}
cpoints=ent.grep(Sketchup::ConstructionPoint)
ent.erase_entities(del,cpoints)
end
divide_face