convert() from scope->world then world->scope gives unexpected results

1534
6
07-08-2020 05:13 AM
DaveLajoie
New Contributor

I have a problem, where I am using convert() to convert scope to world space, apply some world space operation, and then convert it back to scope. based on shape orientation, it either works or behave with unexpected results.

Here is my test case

/**
 * File:    transformBug.cga
 * Created: 8 Jul 2020 11:07:40 GMT
 * Author:  dave.lajoie
 */

version "2019.1"

getScopeInWorld =
     [ convert( x, scope, world, pos, 0,0,0 ) ,
       convert( y, scope, world, pos, 0,0,0 ) ,
       convert( z, scope, world, pos, 0,0,0 ) ]

convertWorldToScope(inX, inY, inZ) =
     [ convert( x, world, scope, pos, inX , inY , inZ ) ,
       convert( y, world, scope, pos, inX , inY , inZ ) ,
       convert( z, world, scope, pos, inX , inY , inZ ) ]

getScopeFromWorld =
    convertWorldToScope(
        getScopeInWorld[ 0 ] ,
        getScopeInWorld[ 1 ] ,
        getScopeInWorld[ 2 ] )

printData( prefix ) -->
    print( "-----------" + prefix + "-----------" )
    print( prefix + " scope.sx             : " + scope.sx )
    print( prefix + " scope.sy             : " + scope.sy )
    print( prefix + " scope.sz             : " + scope.sz )
    print( prefix + " getScopeInWorld[0]   : " + getScopeInWorld[0] )
    print( prefix + " getScopeInWorld[1]   : " + getScopeInWorld[1] )
    print( prefix + " getScopeInWorld[2]   : " + getScopeInWorld[2] )
    print( prefix + " getScopeFromWorld[0] : " + getScopeFromWorld[0]  )
    print( prefix + " getScopeFromWorld[1] : " + getScopeFromWorld[1]  )
    print( prefix + " getScopeFromWorld[2] : " + getScopeFromWorld[2]  )

PutCube -->
    s(10,10,10)
    i("builtin:cube")
    comp(f){ top    : color(1,0,0) X. |
             bottom : color(0,1,0) X. |
             side   : color(0,0,1) X. }

@StartRule
TransformTest -->
    PutCube
    doNoAlignScope
    doAlignScopeToAxes
    doAlignScopeToAxesX
    doAlignScopeToAxesY
    doAlignScopeToAxesZ
    doAlignScopeToGeometryYupLargest0
    doAlignScopeToGeometryZupLargest0

doNoAlignScope -->
    printData( "No alignScope" )
    Done.

doAlignScopeToAxes -->
    alignScopeToAxes()
    printData( "alignScopeToAxes()" )
    Done.

doAlignScopeToAxesX -->
    alignScopeToAxes(x)
    printData( "alignScopeToAxes(x)" )
    Done.

doAlignScopeToAxesY -->
    alignScopeToAxes(y)
    printData( "alignScopeToAxes(y)" )
    Done.

doAlignScopeToAxesZ -->
    alignScopeToAxes(z)
    printData( "alignScopeToAxes(z)" )
    Done.

doAlignScopeToGeometryYupLargest0 -->
    alignScopeToGeometry(yUp, largest, 0)
    printData( "alignScopeToGeometry(yUp, largest, 0)" )
    Done.

doAlignScopeToGeometryZupLargest0 -->
    alignScopeToGeometry(zUp, largest, 0)
    printData( "alignScopeToGeometry(zUp, largest, 0)" )
    Done.

Initial Shape
v0 ( -30.0, 0, 30.0 )
v1 ( -30.0, 0, -30.0 )
v2 ( 30.0, 0, -30.0 )
v3 ( 30.0, 0, 30.0 )

Conclusion:
whenever the shape is mostly aligned in XYZ,
the convert() function appears to work correctly ( 3 cases ) when the return value is approx the same value as the scope.

-----------No alignScope-----------
No alignScope scope.sx : 60
No alignScope scope.sy : 0
No alignScope scope.sz : 60
No alignScope getScopeInWorld[0] : 30
No alignScope getScopeInWorld[1] : 0
No alignScope getScopeInWorld[2] : -29.99999737731673
No alignScope getScopeFromWorld[0] : 59.99999618530273 >>>>>> expected result <<<<<<<
No alignScope getScopeFromWorld[1] : 0 >>>>>> expected result <<<<<<<
No alignScope getScopeFromWorld[2] : 60.00000381469727 >>>>>> expected result <<<<<<<
-----------alignScopeToAxes()-----------
alignScopeToAxes() scope.sx : 59.99999618530273
alignScopeToAxes() scope.sy : 0
alignScopeToAxes() scope.sz : 59.99999618530273
alignScopeToAxes() getScopeInWorld[0] : -30
alignScopeToAxes() getScopeInWorld[1] : 0
alignScopeToAxes() getScopeInWorld[2] : -29.99999737731696
alignScopeToAxes() getScopeFromWorld[0] : 0
alignScopeToAxes() getScopeFromWorld[1] : 0
alignScopeToAxes() getScopeFromWorld[2] : 5.2453660828177817e-06
-----------alignScopeToAxes(x)-----------
alignScopeToAxes(x) scope.sx : 59.99999618530273
alignScopeToAxes(x) scope.sy : 0
alignScopeToAxes(x) scope.sz : 59.99999618530273
alignScopeToAxes(x) getScopeInWorld[0] : -30.00000000000011
alignScopeToAxes(x) getScopeInWorld[1] : 0
alignScopeToAxes(x) getScopeInWorld[2] : -29.99999737731696
alignScopeToAxes(x) getScopeFromWorld[0] : -2.2832793598534518e-13
alignScopeToAxes(x) getScopeFromWorld[1] : 0
alignScopeToAxes(x) getScopeFromWorld[2] : 5.2453660828177817e-06
-----------alignScopeToAxes(y)-----------
alignScopeToAxes(y) scope.sx : 60
alignScopeToAxes(y) scope.sy : 0
alignScopeToAxes(y) scope.sz : 60
alignScopeToAxes(y) getScopeInWorld[0] : 30
alignScopeToAxes(y) getScopeInWorld[1] : 0
alignScopeToAxes(y) getScopeInWorld[2] : -29.99999737731673
alignScopeToAxes(y) getScopeFromWorld[0] : 59.99999618530273 >>>>>> expected result <<<<<<<
alignScopeToAxes(y) getScopeFromWorld[1] : 0 >>>>>> expected result <<<<<<<
alignScopeToAxes(y) getScopeFromWorld[2] : 60.00000381469727 >>>>>> expected result <<<<<<<
-----------alignScopeToAxes(z)-----------
alignScopeToAxes(z) scope.sx : 59.99999618530273
alignScopeToAxes(z) scope.sy : 0
alignScopeToAxes(z) scope.sz : 59.99999618530273
alignScopeToAxes(z) getScopeInWorld[0] : -30.00000000000011
alignScopeToAxes(z) getScopeInWorld[1] : 0
alignScopeToAxes(z) getScopeInWorld[2] : -29.99999737731696
alignScopeToAxes(z) getScopeFromWorld[0] : -2.2832793598534518e-13
alignScopeToAxes(z) getScopeFromWorld[1] : 0
alignScopeToAxes(z) getScopeFromWorld[2] : 5.2453660828177817e-06
-----------alignScopeToGeometry(yUp, largest, 0)-----------
alignScopeToGeometry(yUp, largest, 0) scope.sx : 59.99999618530273
alignScopeToGeometry(yUp, largest, 0) scope.sy : 0
alignScopeToGeometry(yUp, largest, 0) scope.sz : 59.99999618530273
alignScopeToGeometry(yUp, largest, 0) getScopeInWorld[0] : 29.99999618530273
alignScopeToGeometry(yUp, largest, 0) getScopeInWorld[1] : 0
alignScopeToGeometry(yUp, largest, 0) getScopeInWorld[2] : -29.99999737731696
alignScopeToGeometry(yUp, largest, 0) getScopeFromWorld[0] : 59.99999237060547 >>>>>> expected result <<<<<<<
alignScopeToGeometry(yUp, largest, 0) getScopeFromWorld[1] : 0 >>>>>> expected result <<<<<<<
alignScopeToGeometry(yUp, largest, 0) getScopeFromWorld[2] : 60 >>>>>> expected result <<<<<<<
-----------alignScopeToGeometry(zUp, largest, 0)-----------
alignScopeToGeometry(zUp, largest, 0) scope.sx : 59.99999618530273
alignScopeToGeometry(zUp, largest, 0) scope.sy : 59.99999618530273
alignScopeToGeometry(zUp, largest, 0) scope.sz : 0
alignScopeToGeometry(zUp, largest, 0) getScopeInWorld[0] : -30.00000000000006
alignScopeToGeometry(zUp, largest, 0) getScopeInWorld[1] : 1.3113416343912832e-06
alignScopeToGeometry(zUp, largest, 0) getScopeInWorld[2] : -29.99999737731719
alignScopeToGeometry(zUp, largest, 0) getScopeFromWorld[0] : 1.3113416343912832e-06
alignScopeToGeometry(zUp, largest, 0) getScopeFromWorld[1] : 3.9340243347396608e-06
alignScopeToGeometry(zUp, largest, 0) getScopeFromWorld[2] : 2.6226828140352154e-06

Rotate InitialShape along Y by 45 degs
v0 ( -42.42640686035156, 0, 0 )
v1 ( 0, 0, -42.42640686035156 )
v2 ( 42.42640686035156, 0, 0 )
v3 ( 0, 0, 42.42640686035156 )

Conclusion:
whenever the shape is NOT aligned in XYZ ( rotated )
the convert() function appears to no work correctly, clearly I am missing something.

-----------No alignScope-----------
No alignScope scope.sx : 60
No alignScope scope.sy : 0
No alignScope scope.sz : 60
No alignScope getScopeInWorld[0] : 42.42640686035156
No alignScope getScopeInWorld[1] : 0
No alignScope getScopeInWorld[2] : 0
No alignScope getScopeFromWorld[0] : -17.57359313964844
No alignScope getScopeFromWorld[1] : 0
No alignScope getScopeFromWorld[2] : 42.42640686035156
-----------alignScopeToAxes()-----------
alignScopeToAxes() scope.sx : 84.85282135009766
alignScopeToAxes() scope.sy : 0
alignScopeToAxes() scope.sz : 84.85282135009766
alignScopeToAxes() getScopeInWorld[0] : -42.42641067504883
alignScopeToAxes() getScopeInWorld[1] : 0
alignScopeToAxes() getScopeInWorld[2] : -42.42640686035156
alignScopeToAxes() getScopeFromWorld[0] : -84.85281372070313
alignScopeToAxes() getScopeFromWorld[1] : 0
alignScopeToAxes() getScopeFromWorld[2] : 0
-----------alignScopeToAxes(x)-----------
alignScopeToAxes(x) scope.sx : 84.85282135009766
alignScopeToAxes(x) scope.sy : 0
alignScopeToAxes(x) scope.sz : 84.85282135009766
alignScopeToAxes(x) getScopeInWorld[0] : -42.42640686035156
alignScopeToAxes(x) getScopeInWorld[1] : 5.2453669923124835e-06
alignScopeToAxes(x) getScopeInWorld[2] : 42.42641448974609
alignScopeToAxes(x) getScopeFromWorld[0] : -84.85281372070313
alignScopeToAxes(x) getScopeFromWorld[1] : -2.6226834961562418e-06
alignScopeToAxes(x) getScopeFromWorld[2] : 7.62939453125e-06
-----------alignScopeToAxes(y)-----------
alignScopeToAxes(y) scope.sx : 60
alignScopeToAxes(y) scope.sy : 0
alignScopeToAxes(y) scope.sz : 60
alignScopeToAxes(y) getScopeInWorld[0] : 42.42640686035156
alignScopeToAxes(y) getScopeInWorld[1] : 0
alignScopeToAxes(y) getScopeInWorld[2] : 0
alignScopeToAxes(y) getScopeFromWorld[0] : -17.57359313964844
alignScopeToAxes(y) getScopeFromWorld[1] : 0
alignScopeToAxes(y) getScopeFromWorld[2] : 42.42640686035156
-----------alignScopeToAxes(z)-----------
alignScopeToAxes(z) scope.sx : 84.85282135009766
alignScopeToAxes(z) scope.sy : 0
alignScopeToAxes(z) scope.sz : 84.85282135009766
alignScopeToAxes(z) getScopeInWorld[0] : 42.42641067504883
alignScopeToAxes(z) getScopeInWorld[1] : -5.2453669923124835e-06
alignScopeToAxes(z) getScopeInWorld[2] : -42.42640686035156
alignScopeToAxes(z) getScopeFromWorld[0] : 3.814697265625e-06
alignScopeToAxes(z) getScopeFromWorld[1] : 2.6226834961562418e-06
alignScopeToAxes(z) getScopeFromWorld[2] : -3.2425410555377008e-13
-----------alignScopeToGeometry(yUp, largest, 0)-----------
alignScopeToGeometry(yUp, largest, 0) scope.sx : 60
alignScopeToGeometry(yUp, largest, 0) scope.sy : 0
alignScopeToGeometry(yUp, largest, 0) scope.sz : 60
alignScopeToGeometry(yUp, largest, 0) getScopeInWorld[0] : 42.42640686035156
alignScopeToGeometry(yUp, largest, 0) getScopeInWorld[1] : 0
alignScopeToGeometry(yUp, largest, 0) getScopeInWorld[2] : 0
alignScopeToGeometry(yUp, largest, 0) getScopeFromWorld[0] : -17.57359313964844
alignScopeToGeometry(yUp, largest, 0) getScopeFromWorld[1] : 0
alignScopeToGeometry(yUp, largest, 0) getScopeFromWorld[2] : 42.42640686035156
-----------alignScopeToGeometry(zUp, largest, 0)-----------
alignScopeToGeometry(zUp, largest, 0) scope.sx : 60
alignScopeToGeometry(zUp, largest, 0) scope.sy : 60
alignScopeToGeometry(zUp, largest, 0) scope.sz : 0
alignScopeToGeometry(zUp, largest, 0) getScopeInWorld[0] : 4.0531759806089474e-14
alignScopeToGeometry(zUp, largest, 0) getScopeInWorld[1] : 1.3113416343912832e-06
alignScopeToGeometry(zUp, largest, 0) getScopeInWorld[2] : -42.42640686035152
alignScopeToGeometry(zUp, largest, 0) getScopeFromWorld[0] : 9.2725855438402505e-07
alignScopeToGeometry(zUp, largest, 0) getScopeFromWorld[1] : 1.3113416343912832e-06
alignScopeToGeometry(zUp, largest, 0) getScopeFromWorld[2] : 9.2725866807086277e-07

what I would like to do is use the shape origin ( scope.s ) and convert it to world space, apply some operation on world xyz, and then convert it back to scope space.

Assume the following shape ( oddly rotated in all three axis , and translated in 3D space ) where the shape is 60x0x60 in size

I need to flatten the shape in Z, and then extract the scope origin(xyz) in world space, then quantized the xyz to a specified float modulo, then convert back from world xyz into scope space, so I can reset the modified scope to align with the quantized world space coordinates. ( shown by orange arrow )

I was hoping I could use convert() to the conversion back and forth between scope and world.

I am sure I am missing something silly.

Tx

Dave.

0 Kudos
6 Replies
DaveLajoie
New Contributor

I also tried scope->pivot and scope->object without much better results.

0 Kudos
DaveLajoie
New Contributor

Found the solution!

roundToModulo( inFloat , inBaseFloat )  = inBaseFloat * rint( inFloat / inBaseFloat )

computeQuantizedOffsetXZ = 

    [ roundToModulo( getScopeInWorld[0] , BlockWidthModuloSpace  ) - getScopeInWorld[0] ,

      roundToModulo( getScopeInWorld[1] , BlockHeightModuloSpace ) - getScopeInWorld[1] ,

      roundToModulo( getScopeInWorld[2] , BlockLengthModuloSpace ) - getScopeInWorld[2] ]

    t( computeQuantizedOffsetXZ[0] ,

       computeQuantizedOffsetXZ[1] ,

       computeQuantizedOffsetXZ[2] )

0 Kudos
CherylLau
Esri Regular Contributor

Actually, there is a bug with converting from world to scope.  We have to fix that.  Sorry about that.

0 Kudos
DaveLajoie
New Contributor

Great, I thought I was going crazy! tx! any workaround?

0 Kudos
CherylLau
Esri Regular Contributor

No, sorry, no workaround.  We just need to fix it.

0 Kudos
DaveLajoie
New Contributor

Sure! let me know whenever it is being fixed! and tx again!

0 Kudos