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

    Scale non-uniform along vector?

    Scheduled Pinned Locked Moved Developers' Forum
    22 Posts 4 Posters 1.8k Views 4 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

      Hi! Getting stuck on something here.
      Like the subject says, can one Scale non-uniformly along vector with the standard API methods? Or do one have to go hardcore Matrix or something like that.

      I have a 2d group that need some stretching out in 1 direction=vector..
      The group doesent really have to be scaled FROM a certain point, it will get translated to place later anyway.

      So being 2d-geometry to do a normal uniformal scale, I'll just have to give point3d and a scaling factor for it to work.
      That's simple enough but doesen't help me in this case..

      API says:
      t = Geom::Transformation.scaling point, xscale, yscale, zscale
      But, that's fixed on the Global axes while I have an vector + variable for scale factor.

      I think I've seen some code for this but forgot where it was.

      Would be greatful for help in this, thanks.


      scale.vector.jpg

      1 Reply Last reply Reply Quote 0
      • Chris FullmerC Offline
        Chris Fullmer
        last edited by

        I think what you want to do is to first get the transformation of the group/component. Then set the transformation just like you have done there. Then multiply the original transformation by the new one. That will apply your vector one to the existing one. Then set that transformation as the active transformation. Code looks something like this:

        gc = your_group_or_component gc_t = gc.transformation xscale = 1.0 yscale = 2.0 zscale = 1.0 t = Geom::Transformation.scaling [0,0,0], xscale, yscale, zscale new_t = gc_t*t gc.transformation = new_t

        That is working for me.

        Lately you've been tan, suspicious for the winter.
        All my Plugins I've written

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

          Hi Chris!

          Thank you for the code-snippet. So this is what do you call it, objects "local" scaling?

          It might actually work! If doing some tests to see if the "local" x,y,z is on the provided vector direction. The vector will always be perpendicular 90 deg. somehow to the group.

          I will do some tests to see if it can be incorporated in my script.

          Thank you!

          1 Reply Last reply Reply Quote 0
          • Chris FullmerC Offline
            Chris Fullmer
            last edited by

            I'm a little confused by what you mean by scaling along a vector. Is the vector a "local" x,y, or z vector to the component? There is another simple method to apply a transformation. Look at this idea. This takes the existing transformation and makes a temp transformation matrix that is 3 times longer along its y axis. Then it sets the component to use that transformation - effectively scaling it 3 times on its y axis.

            ` gc = my_group_or_component

            gc_t = gc.transformation

            temp_t = gc_t.to_a
            temp_y = temp_t[5]
            temp_t[5] = 3*temp_y

            Geom::Transformation.new(temp_t)
            gc.transformation = temp_t`

            So you can also just use that approach. Its similar to the other way sort of.

            Lately you've been tan, suspicious for the winter.
            All my Plugins I've written

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

              Ah yes. Why scale along vector? I'll try to explain as good as I can.

              There will be an Edge selection on a face that will become the vector(edge.start to edge.end). And the 2d group which scaling will be performed on is glued to the face as well. The scaling will be perpendicular to the edge.
              So If the face is "off" Global axis or the 2d group is rotated 90 deg, normal axis scaling won't work.

              Will have a look on your new code. Might be a better alternative.

              Thanks again.

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                FYI... there are two class methods for transforms that take a vector (not sure if they do non-uniform scaling, you'll have to experiment.)

                Geom::Transformation.translation( vec )
                and
                Geom::Transformation.new( vec )

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • Dan RathbunD Offline
                  Dan Rathbun
                  last edited by

                  Your other option would be to temporarily apply a rotation tranform, and align the group or component with the global axes, apply a non-uniform scaling tranformation, then apply the inverse of the previous rotational tranform.

                  I'm not here much anymore.

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

                    Hm no. Don't know what I was thinking... Back to square 1.. There are a lot of holes in my method needs filling in.

                    Need at least to multiply with excisting transformation, as Chris has shown. Will have to take a better look at the second method he provided, or maybe Dan's suggestions if something better don't come up..

                    Edited: I realize now, what I said about scaling along vector was a bit difficult to understand. I meant scaling along one of the local x,y,z axis IF any of them are perpendicular to the vector(edge).

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

                      Thanks Dan. Appreciate it.

                      I have looked at the API. Can't get the comments working so I miss out a few "goodies" there I think..

                      But as far as I have gotten, scaling Non-uniformly takes 4 arguments. Orgin, scale x, scale y, scale z.

                      You second advice would have to be plan "B". I have thought of doing something like that, but I'll try to avoid it cause there is plenty of transformations done before the group is even on the face.

                      I'm working on a method (Cris code gave me an idea)that might possibly work. Just need to retrieve the group local x,z,y axis? If I can.. This is what I have got so far. Could probably use a case method...
                      You pass in the group, scaling, and vector. Where vector=(edge.start.vector_to(edge.end))

                      def vec_scale(group, scaling, vector)
                      			
                      			#vector need to be parallel or perpendicular or scaling wont work.
                      			
                      			##TRANS- and Center####
                      			gents=group.entities
                      			bbox=group.bounds
                      			bbox_c=bbox.center
                      			  
                      			group_x=group.transformation.xaxis
                      			group_y=group.transformation.yaxis
                      			group_z=group.transformation.zaxis
                      			
                      			if group_x.perpendicular? vector
                      				xscale = scaling
                      			else
                      				xscale = 1
                      			end
                      			
                      			if group_y.perpendicular? vector
                      				yscale = scaling
                      			else
                      				xscale = 1
                      			end
                      			
                      			if group_z.perpendicular? vector
                      				zscale = scaling
                      			else
                      				zscale = 1
                      			end
                      			
                      			t = Geom;;Transformation.scaling(bbox_c, xscale, yscale, zscale)
                      			gents.transform_entities(t, gents.to_a)#Normaly you apply t to group. But I need to do it to entities.
                      		end
                      
                      1 Reply Last reply Reply Quote 0
                      • Dan RathbunD Offline
                        Dan Rathbun
                        last edited by

                        You should know that IF the DynamicComponents extension is loaded, it adds some methods for ComponentInstance and Group instance objects.

                        for Group and ComponentInstance:
                        local_transformation() scaled_size() unscaled_size()

                        for ComponentInstance ONLY:
                        copy() # works like Group.copy()
                        description()

                        and for DC ComponentInstances ONLY:
                        set_last_size(lenx,leny,lenz) last_scaling_factors()

                        I'm not here much anymore.

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

                          Edit: Think the method works now 😍

                          Not 100% tested in all angles yet. Changed my code in previous post.

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

                            Oops. Sorry Dan, must have typed while you post your message.

                            Your info: Really? Did not have a clue about that. Thats is good news for further developpment. Thank you.

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

                              Ah typical 😞 . Too early to celebrate.. It doesent work of axis= face tilted.

                              Get strange new error no implicit conversion to float from nil

                              I guess group_x=group.transformation.xaxisis only gonna work if the group is aligned to global axis. Therefore when tilted it has nothing=nil??

                              1 Reply Last reply Reply Quote 0
                              • Chris FullmerC Offline
                                Chris Fullmer
                                last edited by

                                group.transformation.x_axis

                                is returning the vector of the component's local x axis. It should never return nil I don't think. I can't play with your code at the moment, but maybe later today I can test it out.

                                You should note that its possible/normal? for 2 vectors to perpendicular to the one you're testing against. So it will scale in 2 directions, not just one (I think).

                                Lately you've been tan, suspicious for the winter.
                                All my Plugins I've written

                                1 Reply Last reply Reply Quote 0
                                • TIGT Online
                                  TIG Moderator
                                  last edited by

                                  gt=group.transformation og=gt.origin xa=gt.xaxis ya=gt.yaxis
                                  [ za=face.normal
                                  or za=xa.cross(ya)]
                                  Use a rotation transformation about og and za by the angle_between xa and vector ?
                                  Then do a scaling transformation along the xaxis only to match (vector.length / groupX.bounds.width) [where you have used add_instance on group.entities.parent [==definition] temporarily added to the face.parent.entities, at the origin with no further transformation as groupX ?]
                                  Then invert the rotation transformation...
                                  All done ?

                                  TIG

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

                                    @unknownuser said:

                                    is returning the vector of the component's local x axis

                                    So it IS the local axis we are dealing with here. Since the scaling is only working on Global axis I persumed it wasen't. Thats good then(hopefully).

                                    @unknownuser said:

                                    You should note that its possible/normal? for 2 vectors to perpendicular to the one you're testing against. So it will scale in 2 directions, not just one

                                    Uh oh 😲 That's NOT good! I will do some further testing to se if it fails.

                                    Thanks for all your help.

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

                                      Hello TIG. I typed when your answer came in. Bad timing today πŸ˜„

                                      Will try your code and report back. Looks interesting.

                                      Thanks a million!!

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

                                        I'm not sure I quite understand where to use you code, TIG. When Importing the component definition?
                                        That could be difficult in this case...
                                        This particular tiling is in it's own method. In the plugin there are other "tiling" methods. So cannot do any altering to the component def. before calling the method of choice. Unless I rewrite the definition loader-method. Could be done of course..

                                        In your code: vector.length / groupX.bounds.width. Is that to determine the scale?

                                        The way this feature will work in the plugin, is that the USER determin number of rows, some code like: edge.length/numbers of rows to determin groupX.bounds.width.

                                        So I'll add that part to your code-snippet?

                                        Edited. Changed some info to clarify things, it's not good to write topics saturday nights πŸ˜„:
                                        I think Chris was right about conflicts i vectors(Edge can be perpendicular to 2 axes of course).
                                        So I've scrapped that code..
                                        See if I can incorporate TIG's code, and see if it works. I think I get the idea of it.


                                        fitrow.jpg

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

                                          @unknownuser said:

                                          gt=group.transformation
                                          og=gt.origin
                                          xa=gt.xaxis
                                          ya=gt.yaxis
                                          [za=face.normal
                                          or za=xa.cross(ya)]
                                          Use a rotation transformation about og and za by the angle_between xa and vector ?
                                          Then do a scaling transformation along the xaxis only to match (vector.length / groupX.bounds.width) [where you have used add_instance on group.entities.parent [==definition] temporarily added to the face.parent.entities, at the origin with no further transformation as groupX ?]
                                          Then invert the rotation transformation...
                                          All done ?

                                          Is it that this code is to be used when comp.definition( or group) is at Origin=flat on "ground"?
                                          Cause I get some funky results.. Havent tried "hard" yet. Will elaborate more after lunch....

                                          I've tried something like this where vector is edge:

                                          gt=group.transformation
                                          			og=gt.origin
                                          			xa=gt.xaxis
                                          			ya=gt.yaxis
                                          			za=@face.normal #@face=reference to the face.selection
                                          			za=xa.cross(ya) #??
                                          			
                                          			x_to_vec=xa.angle_between vector
                                          			
                                          			tr1=Geom;;Transformation.rotation(og, za, x_to_vec)#req. rotation angle
                                          			group.transform!(tr1)
                                          			
                                          			ts = Geom;;Transformation.scaling(og, scaling, 1, 1)		
                                          			group.transform!(ts)
                                          			
                                          			tr=tr1.invert!
                                          			group.transform!(tr)
                                          
                                          1 Reply Last reply Reply Quote 0
                                          • jolranJ Offline
                                            jolran
                                            last edited by

                                            BTW:

                                            This special kind of tiling method will not take any rotation(angle) other than 90.degrees as an argument. The group(hatches) will always have to be perpendicular to the edge.

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

                                            Advertisement