• Login
sketchucation logo sketchucation
  • Login
⚠️ Libfredo 15.4b | Minor release with bugfixes and improvements Update

What defines an identity transformation?

Scheduled Pinned Locked Moved Developers' Forum
17 Posts 3 Posters 258 Views 3 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.
  • T Offline
    thomthom
    last edited by 8 Feb 2013, 09:58

    It appear that Geom::Transformation.identity? is set when creating an transformation object with no arguments - not based on the actual value.

    <span class="syntaxdefault"><br /></span><span class="syntaxcomment">#&nbsp;Invalid&nbsp;vector,&nbsp;I&nbsp;know.&nbsp;But&nbsp;you&nbsp;often&nbsp;get&nbsp;this&nbsp;when&nbsp;making<br />#&nbsp;tools&nbsp;with&nbsp;input&nbsp;points&nbsp;etc.<br /></span><span class="syntaxdefault">v&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Vector3d</span><span class="syntaxkeyword">.new(&nbsp;</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0&nbsp;</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">Vector3d</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">)<br /><br /></span><span class="syntaxdefault">tr&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Transformation</span><span class="syntaxkeyword">.new(&nbsp;</span><span class="syntaxdefault">v&nbsp;</span><span class="syntaxkeyword">)<br /></span><span class="syntaxcomment">#<Geom;;Transformation;0x10a5eb90><br /><br /></span><span class="syntaxdefault">tr</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_a<br /></span><span class="syntaxkeyword">[</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">]<br /><br /></span><span class="syntaxdefault">tr</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">identity</span><span class="syntaxkeyword">?<br /></span><span class="syntaxdefault">false<br /><br /></span><span class="syntaxcomment">#&nbsp;---<br /><br /></span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Transformation</span><span class="syntaxkeyword">.new.</span><span class="syntaxdefault">to_a<br /></span><span class="syntaxkeyword">[</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">]<br /><br /></span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Transformation</span><span class="syntaxkeyword">.new.</span><span class="syntaxdefault">identity</span><span class="syntaxkeyword">?<br /></span><span class="syntaxdefault">true<br /></span>
    

    Testing if they are equal:

    <span class="syntaxdefault"><br />Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Transformation</span><span class="syntaxkeyword">.new&nbsp;==&nbsp;</span><span class="syntaxdefault">tr<br />false<br /><br />Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Transformation</span><span class="syntaxkeyword">.new.</span><span class="syntaxdefault">to_a&nbsp;</span><span class="syntaxkeyword">==&nbsp;</span><span class="syntaxdefault">tr</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_a<br />true<br /></span>
    

    Thomas Thomassen — SketchUp Monkey & Coding addict
    List of my plugins and link to the CookieWare fund

    1 Reply Last reply Reply Quote 0
    • T Offline
      thomthom
      last edited by 8 Feb 2013, 10:14

      Also:

      <span class="syntaxdefault"><br />Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Transformation</span><span class="syntaxkeyword">.new.</span><span class="syntaxdefault">to_a<br /></span><span class="syntaxkeyword">[</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">]<br /><br /></span><span class="syntaxcomment">#&nbsp;Using&nbsp;the&nbsp;same&nbsp;numbers;<br /></span><span class="syntaxdefault">Geom</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Transformation</span><span class="syntaxkeyword">.new(&nbsp;[</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">0.0</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">1.0</span><span class="syntaxkeyword">]&nbsp;).</span><span class="syntaxdefault">identity</span><span class="syntaxkeyword">?<br /></span><span class="syntaxdefault">false<br /></span>
      

      #identity? does indeed appear to not be reliable. At least I do not expect it to return false when it's values is the same as when you create an transformation with no arguments.

      Thomas Thomassen — SketchUp Monkey & Coding addict
      List of my plugins and link to the CookieWare fund

      1 Reply Last reply Reply Quote 0
      • A Offline
        AdamB
        last edited by 8 Feb 2013, 10:15

        Its an extremely common optimization to mark transforms that have never been assigned to skip processing. Rather than fiddle around deciding whether a transform "has an effect" based on some epsilon.

        So the method is correct but not complete.

        Developer of LightUp Click for website

        1 Reply Last reply Reply Quote 0
        • T Offline
          thomthom
          last edited by 8 Feb 2013, 10:25

          But surely, the flag could be set in the #new method in all of these cases?

          The flag doesn't have to be computed on every call, just when the matrix' values has been changed - and that's set in #new and #set! . Right?

          Thomas Thomassen — SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund

          1 Reply Last reply Reply Quote 0
          • T Offline
            thomthom
            last edited by 8 Feb 2013, 10:26

            And it's certainly something that would be helpful if the documentation mentioned.

            Thomas Thomassen — SketchUp Monkey & Coding addict
            List of my plugins and link to the CookieWare fund

            1 Reply Last reply Reply Quote 0
            • D Offline
              Dan Rathbun
              last edited by 9 Feb 2013, 05:45

              @thomthom said:

              The flag doesn't have to be computed on every call, just when the matrix' values has been changed - and that's set in #new and #set! . Right?

              ALSO ...

              t3 = Geom::Transformation.axes( Geom::Point3d.new(0, 0, 0), Geom::Vector3d.new(1,0,0), Geom::Vector3d.new(0,1,0), Geom::Vector3d.new(0,0,1)) %(#008000)[>> #<Geom::Transformation:0x753fe38>] t3.identity? %(#008000)[>> false]

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • D Offline
                Dan Rathbun
                last edited by 9 Feb 2013, 05:51

                ALSO ...

                t4 = Geom::Transformation.scaling( 1.0 ) %(#008000)[>> #<Geom::Transformation:0x7621cc0>] t4.identity? %(#008000)[>> false] t4.to_a %(#008000)[>> [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]]

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • D Offline
                  Dan Rathbun
                  last edited by 9 Feb 2013, 06:02

                  I would consider this an API bug, myself.

                  Workaround 1:

                    def indentity_transform?(t)
                      t.to_a == [ 1.0, 0.0, 0.0, 0.0,
                                  0.0, 1.0, 0.0, 0.0,
                                  0.0, 0.0, 1.0, 0.0,
                                  0.0, 0.0, 0.0, 1.0 ]
                    end
                  

                  Workaround 2, a mixin module:

                  module Mixin; end
                  module Mixin;;Identity
                    def indentity?()
                      self.to_a == [ 1.0, 0.0, 0.0, 0.0,
                                     0.0, 1.0, 0.0, 0.0,
                                     0.0, 0.0, 1.0, 0.0,
                                     0.0, 0.0, 0.0, 1.0 ]
                    end
                  end # Mixin module
                  

                  Use mixin to change only individual transforms thus:

                  require("Mixin/indentity.rb")
                  # .. later
                  tran = Geom;;Transformation.scaling( 1.0 )
                  tran.extend(Mixin;;Idenitity)
                  if tran.identity?
                    # do something
                  else
                    # do something else
                  end
                  
                  

                  I'm not here much anymore.

                  1 Reply Last reply Reply Quote 0
                  • T Offline
                    thomthom
                    last edited by 9 Feb 2013, 11:26

                    If you want the optimisation you do the check in #new and #set!

                    Thomas Thomassen — SketchUp Monkey & Coding addict
                    List of my plugins and link to the CookieWare fund

                    1 Reply Last reply Reply Quote 0
                    • A Offline
                      AdamB
                      last edited by 9 Feb 2013, 21:27

                      But if you apply an Identity, it is, by definition, a transform that changes nothing, so no harm done.

                      The method may not cover all cases, but its not really wrong either.

                      The problem, Dan & Thomthom, is floating point precision issues. You can't just compare to an array of 1,0,0,..., because, as you well know, comparing floating point numbers for equality is "A Bad Thing".

                      And sure, stick the test in #Set, and probably triple the execution time of that method and assume its not called often. And keep in mind its not actually catching all cases because of float precision...

                      So then you have to look to generate the full orthonormal transform and check it's unit length etc..

                      We've all been here, walk away. Really. 😄

                      Developer of LightUp Click for website

                      1 Reply Last reply Reply Quote 0
                      • T Offline
                        thomthom
                        last edited by 10 Feb 2013, 00:01

                        @adamb said:

                        But if you apply an Identity, it is, by definition, a transform that changes nothing, so no harm done.

                        Except testing the transformation to be an identity transformation is faster than iterating over thousands of points applying the transformation.

                        And for the usable I was looking for this in my current project the values fed to the transformation object would be true 0 - so floating point precision would not be an issue in this case.

                        But I guess it's just as well to make special case for that in my code instead of the transformation code. Though still wish the API would describe the actual behaviour of #identity?

                        Thomas Thomassen — SketchUp Monkey & Coding addict
                        List of my plugins and link to the CookieWare fund

                        1 Reply Last reply Reply Quote 0
                        • D Offline
                          Dan Rathbun
                          last edited by 10 Feb 2013, 07:07

                          @adamb said:

                          The problem, Dan & Thomthom, is floating point precision issues. You can't just compare to an array of 1,0,0,..., because, as you well know, comparing floating point numbers for equality is "A Bad Thing".

                          (Headsmack!)

                          Right.

                          Well then the API's internal tolerance must be used, so for example compares like:

                          t_identity.xaxis == t_other.xaxis t_identity.xscale.to_l == t_other.xscale.to_l

                          But yes, very slow, new vector and point objects need to be created on both sides of the operator, for all x, y, z, etc. (You might save a bit of time, by using the global objects X_AXIS, Y_AXIS, etc.)

                          Not to mention the overhead of calling all those methods.

                          The API just needs updating / expanding on the C-side of things.

                          I'm not here much anymore.

                          1 Reply Last reply Reply Quote 0
                          • A Offline
                            AdamB
                            last edited by 10 Feb 2013, 10:40

                            I guess the docs could be updated to be:

                            returns true if it is Identity
                            returns false if its undetermined (ie, it might be)

                            @thomthom said:

                            Except testing the transformation to be an identity transformation is faster than iterating over thousands of points applying the transformation.

                            Sure, if that is your bottleneck. Which it probably isn't. 😉

                            Adam

                            Developer of LightUp Click for website

                            1 Reply Last reply Reply Quote 0
                            • T Offline
                              thomthom
                              last edited by 10 Feb 2013, 11:16

                              It's part of it. For when the tool is being used with live preview and thousands of points are being constantly computed - every set of iteration eats some time.

                              The absolute biggest is how slow SketchUp is to add geometry. But that's not a whole lot I can do anything about.

                              Thomas Thomassen — SketchUp Monkey & Coding addict
                              List of my plugins and link to the CookieWare fund

                              1 Reply Last reply Reply Quote 0
                              • D Offline
                                Dan Rathbun
                                last edited by 10 Feb 2013, 11:23

                                FYI: I DID notice that when you use clone() on an identity transform, that the new one correctly has the identity flag set true.

                                I'm not here much anymore.

                                1 Reply Last reply Reply Quote 0
                                • D Offline
                                  Dan Rathbun
                                  last edited by 10 Feb 2013, 11:42

                                  How about this instead for simplicity, and to test using SketchUp's internal tolerance?

                                  module WhatEver
                                   
                                    ZERO = 0.0.to_l
                                    UNIT = 1.0.to_l
                                    IDENT = [ UNIT, ZERO, ZERO, ZERO,
                                              ZERO, UNIT, ZERO, ZERO,
                                              ZERO, ZERO, UNIT, ZERO,
                                              ZERO, ZERO, ZERO, UNIT
                                            ]
                                   
                                    def indentity_transform?(t)
                                      #
                                      t.to_a.map{|m|m.to_l} == IDENT
                                      #
                                    end
                                   
                                  end # module WhatEver
                                  

                                  I'm not here much anymore.

                                  1 Reply Last reply Reply Quote 0
                                  • D Offline
                                    Dan Rathbun
                                    last edited by 10 Feb 2013, 11:48

                                    Which also leads to the conclusion that the Geom::Transformation class needs a properly overriden comparison methods <=>(), ==(), and eql?() ...

                                    💭

                                    I'm not here much anymore.

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

                                    Advertisement