sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Draw parallel line, distance=11

    Scheduled Pinned Locked Moved Developers' Forum
    21 Posts 5 Posters 3.2k Views 5 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • jolranJ Offline
      jolran
      last edited by

      A, what the heck. Here some very simple code suggestion. I don't know if it's this you want to do.

      Sure this can be implemented by math calculations. But using vectors and points + maybe adding length.class assures you'll be within Sketchup tolerance..
      I'll probably do different if communicating with exterior program. But always convert to Point3d objects.

      prompts = ["length", "Run","height","Rise","Total Rises"]
       defaults = [36.0,10.0,1.0,7.75,7]
       input = UI.inputbox prompts, defaults, "Tread."
       
       
       len, run, heit, rise, n_steps = input #len(a) not used in original ?
       ent = Sketchup.active_model.entities
       
       # Assuming height is meant startdistance under ORIGIN
      pts = []
      
      v_rise = Geom;;Vector3d.new(0,0,rise)
      v_run = Geom;;Vector3d.new(0,run,0)
      startpoint = Geom;;Point3d.new(0,0,-heit).offset!(v_rise.reverse)
      p1 = startpoint.offset(v_run)
      
      pts << p1
      pts << startpoint
      
      for i in (0...n_steps)
      
      	pts << startpoint = startpoint.offset(v_rise)
      	pts << startpoint = startpoint.offset(v_run)
      	
      end
      
      pts << startpoint.offset(v_rise.reverse)
      
      f = ent.add_face(pts)
      f.pushpull(20)
      
      1 Reply Last reply Reply Quote 0
      • D Offline
        davesexcel
        last edited by

        Thanks,I still need the required depth 11". That would be where the math would come in.

        1 Reply Last reply Reply Quote 0
        • S Offline
          slbaumgartner
          last edited by

          Aha, you mislead us somewhat by not stating your real question at first! Also, please review the SketchUp API definitions of "Edge" and "line" - they are not the same thing. An "Edge" is a finite segment with specified start and end points. A "line" is an infinite geometric abstraction (it has no start or end) that SketchUp represents as an Array containing either a Point3d and a Vector3d or two Point3d objects. It is an unfortunate historical mistake that the method to create an Edge is named Entities#add_line.

          So anyway here's an outline of how to do it (don't have time to write and check Ruby code just now, if you can't follow let us know and I'll work it up when I have a chance):

          1. draw your upper stair Edges as in your picture, all the risers and tread runs
          2. create a line horizontally through the bottom-most end point: hline= [bottompoint, green vector]
          3. create a line vertically through the top-most end point: vline=[toppoint, -blue vector]
          4. create a vector through any two of the stair tread outer vertices
          5. use this vector in my previous code to get an offset vector for the parallel line, but don't draw the Edge using it.
          6. apply the offset to any of the outer stair tread vertices to get a point on the parallel line
          7. create the parallel line using this point and the vector from step 4
          8. use Geom::intersect_line_line to get the intersection points between the lines from steps 2, 3, and 7
          9. draw your final Edges using the points from step 8

          PS: you could also do all this using trig, per some previous posts. I prefer to use geometry construction so as to let SketchUp worry about numeric precision and such.

          1 Reply Last reply Reply Quote 0
          • jolranJ Offline
            jolran
            last edited by

            @unknownuser said:

            Aha, you mislead us somewhat by not stating your real question at first!

            Indeed.

            I think Slbaumgartner wraps it up pretty nicely.

            1 Reply Last reply Reply Quote 0
            • S Offline
              slbaumgartner
              last edited by

              Found a few minutes...try this:

              
                def draw_stringer(rise, run, tread_thickness, numsteps)
                  ents=Sketchup.active_model.active_entities
                  # offset vectors for rise and run
                  risevect = Geom;;Vector3d.new([0,0,0], [0,0,rise])
                  runvect = Geom;;Vector3d.new([0,0,0], [0,run,0])
                  # arbitrarily start at the global SketchUp origin
                  basepoint = ORIGIN
                  # draw the upper profile of the stringer
                  # first step adjusted for tread thickness
                  corner = basepoint.offset(Geom;;Vector3d.new([0,0,0], [0,0,rise-tread_thickness]))
                  ents.add_line(basepoint, corner)
                  # remember first corner for later
                  firstcorner = corner
                  basepoint = corner.offset(runvect)
                  ents.add_line(corner, basepoint)
                  # now do the rest of the steps
                  2.upto(numsteps) do
                    corner = basepoint.offset(risevect)
                    ents.add_line(basepoint, corner)
                    basepoint = corner.offset(runvect)
                    ents.add_line(corner, basepoint)
                  end
                  # create the baseline and top plumb line
                  baseline = [ORIGIN, [0,1,0]]
                  plumbline = [basepoint, [0,0,-1]]
                  # create the offset vector to the other line
                  cornervect = Geom;;Vector3d.new(firstcorner, corner)
                  normalvect = cornervect*[0,0,1]
                  offsetvect = cornervect*normalvect
                  offsetvect.length=11
                  # create the two corners for the remaining Edges
                  # get a point on the bottom line by offsetting from any top corner
                  refpoint = corner.offset(offsetvect)
                  oppline = [refpoint, cornervect]
                  bottomcorner = Geom;;intersect_line_line(oppline, baseline)
                  topcorner = Geom;;intersect_line_line(oppline, plumbline)
                  # add the Edges
                  ents.add_line(ORIGIN, bottomcorner)
                  ents.add_line(bottomcorner, topcorner)
                  finaledge = ents.add_line(topcorner, basepoint)
                  # fill in the Face
                  finaledge.find_faces()
                end
              
              
              1 Reply Last reply Reply Quote 0
              • D Offline
                davesexcel
                last edited by

                Very nice indeed. I adjusted it to account for the riser thickness, this needs to be cut off at the back. And it does work for any size string.

                thanks.

                How can I change the basepoint from original to (0,1+rise_thickness,0) ?

                 def draw_stringer(rise, run, tread_thickness, numsteps)
                             
                        ents=Sketchup.active_model.active_entities
                		rise=7.75
                		run=10
                		tread_thickness=1
                		numsteps=7
                		string=11
                        rise_thickness=0.5
                        # offset vectors for rise and run
                        risevect = Geom;;Vector3d.new([0,0,0], [0,0,rise])
                        runvect = Geom;;Vector3d.new([0,0,0], [0,run,0])
                	#<<<<<<<<<<<<<<
                        lstrun = Geom;;Vector3d.new([0,0,0], [0,(run-rise_thickness),0])
                	#<<<<<<<<<<<<<<<<<<<<
                        # arbitrarily start at the global SketchUp origin
                        basepoint = ORIGIN
                        # draw the upper profile of the stringer
                        # first step adjusted for tread thickness
                        corner = basepoint.offset(Geom;;Vector3d.new([0,0,0], [0,0,rise-tread_thickness]))
                        ents.add_line(basepoint, corner)
                        # remember first corner for later
                        firstcorner = corner
                        basepoint = corner.offset(runvect)
                        ents.add_line(corner, basepoint)
                        # now do the rest of the steps
                        2.upto(numsteps-2) do
                          corner = basepoint.offset(risevect)
                          ents.add_line(basepoint, corner)
                          basepoint = corner.offset(runvect)
                          ents.add_line(corner, basepoint)
                        end
                        # <<<<<<<<<<<<last run
                		corner = basepoint.offset(risevect)
                          ents.add_line(basepoint, corner)
                		basepoint = corner.offset(lstrun)
                          ents.add_line(corner, basepoint)
                
                        # create the baseline and top plumb line
                        baseline = [ORIGIN, [0,1,0]]
                        plumbline = [basepoint, [0,0,-1]]
                        # create the offset vector to the other line
                        cornervect = Geom;;Vector3d.new(firstcorner, corner)
                        normalvect = cornervect*[0,0,1]
                        offsetvect = cornervect*normalvect
                        offsetvect.length=string
                        # create the two corners for the remaining Edges
                        # get a point on the bottom line by offsetting from any top corner
                        refpoint = corner.offset(offsetvect)
                        oppline = [refpoint, cornervect]
                        bottomcorner = Geom;;intersect_line_line(oppline, baseline)
                        topcorner = Geom;;intersect_line_line(oppline, plumbline)
                        # add the Edges
                        ents.add_line(ORIGIN, bottomcorner)
                        ents.add_line(bottomcorner, topcorner)
                        finaledge = ents.add_line(topcorner, basepoint)
                        # fill in the Face
                        finaledge.find_faces()
                 
                
                      end
                
                1 Reply Last reply Reply Quote 0
                • S Offline
                  slbaumgartner
                  last edited by

                  The only things that depend on the starting point are the three places that use ORIGIN. That's an advantage of using offset vectors instead of formulas to create vertex points. So, at the top, define

                  startpoint = [0, 1+riserthickness, 0]

                  and replace ORIGIN with startpoint in the three locations. I didn't include any other error checking, but as a precaution against when riserthickness=0 you might want to change the definition of baseline to

                  baseline = [startpoint, [0, -1, 0]]

                  so that the two points will never be the same (which would cause a SketchUp error). A line does not have a direction, so it does not matter that the second point is "in front" instead of "in back" of startpoint.

                  1 Reply Last reply Reply Quote 0
                  • D Offline
                    davesexcel
                    last edited by

                    @slbaumgartner said:

                    ....

                    Thanks alot,
                    How do I pushpull this?

                    I am trying
                    finaledge.pushpull 1
                    and
                    face.pushpull 1
                    nothing seems to be happening.

                    1 Reply Last reply Reply Quote 0
                    • J Offline
                      Jim
                      last edited by

                      Do you have the Ruby Console open while testing your code? It will show you errors that occur.

                      An Edge is not something that an be pushpulled. Faces can be. Unfortunately, using find_faces does not give you a list of found faces. So you need to find the created face yourself. The code might look something like this:

                      face = ents.grep(Sketchup;;Face).first
                      
                      if face
                        face.pushpull(tread_thickness)
                      end
                      

                      Hi

                      1 Reply Last reply Reply Quote 0
                      • D Offline
                        davesexcel
                        last edited by

                        Thanks

                        1 Reply Last reply Reply Quote 0
                        • 1
                        • 2
                        • 2 / 2
                        • First post
                          Last post
                        Buy SketchPlus
                        Buy SUbD
                        Buy WrapR
                        Buy eBook
                        Buy Modelur
                        Buy Vertex Tools
                        Buy SketchCuisine
                        Buy FormFonts

                        Advertisement