Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Why are my Relative Transformation Values not 0?

    Cinema 4D SDK
    python r21
    4
    11
    898
    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.
    • ferdinandF
      ferdinand
      last edited by ferdinand

      @blastframe said in Why are my Relative Transformation Values not 0?:

      #-3.552713678800501e-15

      That is zero, at least as far as computer scientists programmers are concerned. That is a number with 14 zeros after the comma and then 3552 etc. The reason why this is happening is floating point precision.

      Cheers,
      zipit

      MAXON SDK Specialist
      developers.maxon.net

      ? 1 Reply Last reply Reply Quote 1
      • ?
        A Former User @ferdinand
        last edited by

        @zipit Thank you. So how do I compare it to 0? Currently it does not equate to zero.

        1 Reply Last reply Reply Quote 0
        • ?
          A Former User
          last edited by A Former User

          I found this solution on StackOverflow

          def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
              return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
          

          This seems to address the issue.

          I am still confused as to why the Vectors do not compare equally though:

          print obj[c4d.ID_BASEOBJECT_REL_POSITION] == c4d.Vector(0, 0, 0)
          #False
          

          It seems like the floating point issues would be addressed in Vector.__eq__ and Vector.__ne__

          1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand
            last edited by ferdinand

            Hi,

            there is c4d.utils.CompareFloatTolerant(a, b) although the function is a bit of a black-box. You could also write your function, the problem here is that you might run into floating point precision problems depending on how accurate you want that function to be. The utils function is addressing that problem.

            COMPARE_DELTA = 1e-10
            
            a = 0
            b = 3.1415e-14
            
            print "a:", a, "b:", b
            print "a == b:", a == b
            
            tolerant_compare = lambda a, b: abs(a - b) <= COMPARE_DELTA
            
            print "tolerant compare:", tolerant_compare(a, b)
            
            a: 0 b: 3.1415e-14
            a == b: False
            tolerant compare: True
            

            edit: yes, the stack overflow snippet addresses your problem, it is a slightly fancier version of my lambda.

            FYI: If you are not interested only in a single component of a vector, you can also always evaluate the squared length of the difference vector of the two vectors you want to compare.

            Cheers,
            zipit

            MAXON SDK Specialist
            developers.maxon.net

            ? 1 Reply Last reply Reply Quote 1
            • ?
              A Former User @ferdinand
              last edited by A Former User

              @zipit Your lambda is working better for my current project than the StackOverflow function. I assume this is because of the tolerance? Regardless, thank you very much for your help!!

              1 Reply Last reply Reply Quote 0
              • ferdinandF
                ferdinand
                last edited by

                Jeah, mine is rather tolerant, it bascially ignores everything after the 9th digit. So use with care 😉

                MAXON SDK Specialist
                developers.maxon.net

                ? 1 Reply Last reply Reply Quote 0
                • ?
                  A Former User @ferdinand
                  last edited by

                  @zipit Will do. Thank you!

                  1 Reply Last reply Reply Quote 0
                  • M
                    m_adam
                    last edited by

                    Hi @blastframe just to clarify how c4d.utils.CompareFloatTolerant works, this actually performs a check based on the bit representation.
                    It's not 100% safe but would work in most of Cinema 4D case and it's way faster than a real comparison.

                    For more information about it, see .

                    Cheers,
                    Maxime.

                    MAXON SDK Specialist

                    Development Blog, MAXON Registered Developer

                    1 Reply Last reply Reply Quote 0
                    • ferdinandF
                      ferdinand
                      last edited by

                      Hi,

                      what I meant with "is a bit of a black box" was, that it remains unclear to me, what the function considers "sufficiently close to each other". Does that mean it mimics the rounding behavior of the Cinema 4D app or does it mean that it analyzes the bit-patterns of the operands for avalanche patterns that indicate a precision error?

                      I did not want to imply that it is broken, because I never actually bothered using or testing it, because of the uncertainty of its description.

                      Cheers,
                      zipit

                      MAXON SDK Specialist
                      developers.maxon.net

                      1 Reply Last reply Reply Quote 0
                      • P
                        PluginStudent
                        last edited by

                        The source code of the C++ version of CompareFloatTolerant() is actually available in the frameworks\cinema.framework\source\ge_ieee.cpp and/or \frameworks\core.framework\source\maxon\general_math.cpp file of the C++ SDK. I assume the Python version just calls the C++ function.

                        1 Reply Last reply Reply Quote 1
                        • First post
                          Last post