Draw concave roof using Ruby API

How can I draw a concave roof like this using the ruby API? Currently I’m drawing it straight with four triangle faces. I would like to draw it concave but can’t figure out how.

The base is always square and the peak/point is always above centered 1/2 of width of square.

create the profile and use profile.followme(path)


1 Like

Draw a curved vertical face [vertical-line/base-line/arc] located mid-side on one edge of the square face ‘base’, and then use followme on that face, around the square’s edges used as a the path [taking into account the now split edge with the temp vertical face]

I was afraid I couldn’t figure out how to create the arc. I was thinking about using a loop and drawing each face then softening the edges in between.

You can easily draw an edge to make a triangular facet.
You already have the start/end point - needed for the arc.
You then have the plane of the face.
From that you can get the ‘normal’ for the arc.
You need to do some trigonometry to work out the center of the desired arc.
There are various permutations of how the arc starts/ends and its radius…
As the designer that’s your decision.

Ok thanks to everyone for your help. This formula works but there is a flaw somewhere because if fails if I set the width to 48.

def draw_concave(ent,width)
  half = width/2
  b = ent.add_face([0,0,0],[0,width,0],[width,width,0],[width,0,0])
  path = b.edges
  center = [half,0-(half),width]
  edges = ent.add_arc(center,[0,0,1],[1,0,0],width*1.11806,206.565.degrees,243.435.degrees,96)
  edges.push ent.add_line([half,0,0],[half,half,0])
  edges.push ent.add_line([half,half,0],[half,half,half])
  f = ent.add_face(edges)


setting the width to 12 works, but 24 causes a bug splat. Hmm I’ve got the logic wrong somewhere.

My two cents worth

mod = Sketchup.active_model
ent = mod.active_entities
sel = mod.selection
vue = mod.active_view
val = UI.inputbox(["Length of Side:","Bulge of Arc:"],[10.feet,1.feet],"Concave Roof")
return unless val
side,bulge = val;half=side/2
pts = [[0,0,0],[0,side,0],[side,side,0],[side,0,0]]
fac = ent.add_face(pts)
pts = [[side,half,0],[half,half,0],[half,half,half]]
edg = ent.add_edges(pts)
ctr = Geom::Point3d.linear_combination(0.5,pts[0],0.5,pts[2])
mp1 = Geom::Point3d.linear_combination(0.5,ctr,0.5,pts[0])
mp2 = Geom::Point3d.linear_combination(0.5,ctr,0.5,pts[2])
tr1 = Geom::Transformation.rotation(ctr,[0,-1,0], 90.degrees)
tr2 = Geom::Transformation.rotation(ctr,[0,-1,0],-90.degrees)
cv1 = ctr.vector_to(pts[0]).normalize;
cv1.transform! tr1;#p cv1
cv2 = ctr.vector_to(pts[2]).normalize
cv2.transform! tr2; #p cv2
int = Geom.intersect_line_line([mp1,cv1],[mp2,cv2])
rad = int.distance(ctr);#ent.add_cpoint(int)
ang = int.vector_to(pts[0]).angle_between(int.vector_to(pts[2]))
arc = ent.add_arc(int,int.vector_to(pts[2]),[0,-1,0],rad,0,ang,8)
arc[0].faces[0].followme fac.edges
ent.grep(Sketchup::Face){|f| f.reverse! if f.normal.z<0}

That’s way over my head. I’ll have to break it down an figure out what is actually happening. Sometime I wish knowledge was something I could purchase. :wink:

Now sometimes the faces are drawn reversed. How or why? How can I detect this and reverse the faces?

add this to the previous code

ent.grep(Sketchup::Face){|f| f.reverse! if f.normal.z<0}

Thank to everyone for your help. Your code works great @sdmitch.


This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.