Having some transformation problems

I’ve written a script that puts down a progression of a component when it transitions from one transformation to another. It works fairly well, except if the axis in the component is different from the selection start axis as can be seen in this vid:

I’m thinking that my starting transformation is wrong, but I can’t for the life of me figure out how I can transform the initial transform so that it’s right. And if I have to change the initial, I will definitely need to change the final to agree with the change.

Anyone have any ideas? Here is the relivant code:

        # I probably need to use this somewhere, right?
        t1 = @component_instance.transformation

        from = Geom::Transformation.new(
                @ps[START ][ORIGIN],
                @ps[START ][X_AXIS] - @ps[START ][ORIGIN],
                @ps[START ][Y_AXIS] - @ps[START ][ORIGIN])

        to   = Geom::Transformation.new(
                @ps[FINISH][ORIGIN],
                @ps[FINISH][X_AXIS] - @ps[FINISH][ORIGIN],
                @ps[FINISH][Y_AXIS] - @ps[FINISH][ORIGIN])
        
        for i in (0..@@segments) # TODO: remember to change 0 back to 1
            t2 = Geom::Transformation.interpolate(from, to, i.to_f/@@segments)

            instance = entities.add_instance(component_def, t2)
        end

In case it’s not clear, @ps[START] is an array of the 1st three points picked, and @ps[FINISH] are the last.

I’m thinking that I need to do something like transform the from through t1 and have to go through an intermediate transform, but I’m still not exactly sure.

Yes.

With your tool, the user will get two points. Then likely they’ll enter a number of copies in the VCB.

(In SketchUp it’s tranditional to allow the user to type “x3” (ie a “x” prefix" to denote number of times. So your tool’s onUserText callback may need to strip off preceding characters.)

    def translate_components(start_pt, end_pt, num_copies, comp_instance)
      # Make sure the number the user gave in the VCB is an integer:
      num_copies = num_copies.to_i
      # Get a vector from the two points the user gave the tool:
      copy_vector = start_pt.vector_to(end_pt)
      # Divide this vector by the number of copies:
      incremental_length = copy_vector.length / num_copies.to_l
      # Clone the copy_vector for each translation:
      translational_vector = copy_vector.clone
      # Set the translational vector's length:
      translational_vector.length= incremental_length
      # Now use it to create a new incremental translational transform:
      t_incr = Geom::Transformation.translation(translational_vector)
      # Start with the original's transformation:
      t_copy = comp_instance.transformation
      # The model's active entities context:
      ents = Sketchup.active_model.active_entities
      # Iterate for the number of copies applying the incremental transform:
      for n in 1..num_copies
        # Multiply the previous transform by one the incremental transforms:
        t_copy = t_copy * t_incr
        # Add a new instance of the definition:
        ents.add_instance(comp_instance.definition, t_copy)
      end
    end

Now, looking at the above, we could just reuse the copy_vector and shorten it’s length rather than clone it to a new vector. But I don’t know what you might need that complete copy vector path for afterward.

Anyway … this should give you ideas.


Be aware that this copy actually creates new instances, but does not copy the current instance’s properties or any attribute dictionaries that may be attached to the original.

Since I didn’t really use the increment n variable, we could also just use …

      # Iterate for the number of copies applying the incremental transform:
      num_copies.times do
        # Multiply the previous transform by one the incremental transforms:
        t_copy = t_copy * t_incr
        # Add a new instance of the definition:
        ents.add_instance(definition, t_copy)
      end

See Integer#times

Thanks. I’ll take a look.