commit 925ed78f7ea5a7b3e3b8ab91c81215bf2e212c4d
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Jun 4 00:26:40 2021 +0200

    Make it possible for an object to have different 'basicAngles' along each of its axis.

diff --git a/src/main/java/org/distorted/effects/scramble/ScrambleEffect.java b/src/main/java/org/distorted/effects/scramble/ScrambleEffect.java
index 30914588..08b21cb5 100644
--- a/src/main/java/org/distorted/effects/scramble/ScrambleEffect.java
+++ b/src/main/java/org/distorted/effects/scramble/ScrambleEffect.java
@@ -70,7 +70,7 @@ public abstract class ScrambleEffect extends BaseEffect implements EffectListene
   private int mNumDoubleScramblesLeft, mNumScramblesLeft;
   private long mDurationSingleTurn;
   private final Random mRnd;
-  private int mBasicAngle;
+  private int[] mBasicAngle;
   private boolean mRotReady, mPluginReady;
 
   TwistyObject mObject;
@@ -149,7 +149,7 @@ public abstract class ScrambleEffect extends BaseEffect implements EffectListene
         android.util.Log.e("effect", "ERROR: "+mNumDoubleScramblesLeft);
         }
 
-      mController.addRotation(this, axis, rowBitmap, angle*(360/mBasicAngle), durationMillis);
+      mController.addRotation(this, axis, rowBitmap, angle*(360/mBasicAngle[axis]), durationMillis);
 
       mNumScrambles++;
       }
diff --git a/src/main/java/org/distorted/main/RubikSurfaceView.java b/src/main/java/org/distorted/main/RubikSurfaceView.java
index 01976101..7a750887 100644
--- a/src/main/java/org/distorted/main/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/main/RubikSurfaceView.java
@@ -397,7 +397,7 @@ else
     private void finishRotation()
       {
       computeCurrentSpeedInInchesPerSecond();
-      int angle = mPreRender.getObject().computeNearestAngle(mCurrentAngle, mCurrRotSpeed);
+      int angle = mPreRender.getObject().computeNearestAngle(mCurrentAxis,mCurrentAngle, mCurrRotSpeed);
       mPreRender.finishRotation(angle);
       mPreRender.rememberMove(mCurrentAxis,mCurrentRow,angle);
 
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
index 399caf84..457273b3 100644
--- a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
+++ b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
@@ -52,6 +52,8 @@ abstract class TwistyBandagedAbstract extends TwistyObject
            new Static3D(0,0,1)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 4,4,4 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_YELLOW, COLOR_WHITE,
@@ -545,9 +547,9 @@ abstract class TwistyBandagedAbstract extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 4;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyCube.java b/src/main/java/org/distorted/objects/TwistyCube.java
index 92219f61..bbdd50ab 100644
--- a/src/main/java/org/distorted/objects/TwistyCube.java
+++ b/src/main/java/org/distorted/objects/TwistyCube.java
@@ -47,6 +47,8 @@ class TwistyCube extends TwistyObject
            new Static3D(0,0,1)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 4,4,4 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_YELLOW, COLOR_WHITE,
@@ -287,9 +289,9 @@ class TwistyCube extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 4;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyDiamond.java b/src/main/java/org/distorted/objects/TwistyDiamond.java
index bc3ff867..c6c509b8 100644
--- a/src/main/java/org/distorted/objects/TwistyDiamond.java
+++ b/src/main/java/org/distorted/objects/TwistyDiamond.java
@@ -51,6 +51,8 @@ public class TwistyDiamond extends TwistyObject
            new Static3D(     0,-SQ3/3,+SQ6/3)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_ORANGE, COLOR_VIOLET,
@@ -510,9 +512,9 @@ public class TwistyDiamond extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 3;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyDino.java b/src/main/java/org/distorted/objects/TwistyDino.java
index 7f10661a..39a07972 100644
--- a/src/main/java/org/distorted/objects/TwistyDino.java
+++ b/src/main/java/org/distorted/objects/TwistyDino.java
@@ -46,6 +46,8 @@ public abstract class TwistyDino extends TwistyObject
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_YELLOW, COLOR_WHITE,
@@ -236,9 +238,9 @@ public abstract class TwistyDino extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 3;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyHelicopter.java b/src/main/java/org/distorted/objects/TwistyHelicopter.java
index dda1c219..90699f78 100644
--- a/src/main/java/org/distorted/objects/TwistyHelicopter.java
+++ b/src/main/java/org/distorted/objects/TwistyHelicopter.java
@@ -53,6 +53,8 @@ public class TwistyHelicopter extends TwistyObject
            new Static3D(-SQ2/2, -SQ2/2,      0)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 2,2,2,2,2,2 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_YELLOW, COLOR_WHITE,
@@ -403,9 +405,9 @@ public class TwistyHelicopter extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 2;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyIvy.java b/src/main/java/org/distorted/objects/TwistyIvy.java
index 085a03a9..97dda68b 100644
--- a/src/main/java/org/distorted/objects/TwistyIvy.java
+++ b/src/main/java/org/distorted/objects/TwistyIvy.java
@@ -63,6 +63,8 @@ public class TwistyIvy extends TwistyObject
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_YELLOW, COLOR_WHITE,
@@ -426,9 +428,9 @@ public class TwistyIvy extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 3;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyMinx.java b/src/main/java/org/distorted/objects/TwistyMinx.java
index 95feeb30..6300b3ac 100644
--- a/src/main/java/org/distorted/objects/TwistyMinx.java
+++ b/src/main/java/org/distorted/objects/TwistyMinx.java
@@ -61,6 +61,8 @@ abstract class TwistyMinx extends TwistyObject
            new Static3D( SIN54/LEN,    0     ,   -C2/LEN )
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 5,5,5,5,5,5 };
+
   static final int MINX_LGREEN = 0xff53aa00;
   static final int MINX_PINK   = 0xfffd7ab7;
   static final int MINX_SANDY  = 0xffefd48b;
@@ -450,9 +452,9 @@ abstract class TwistyMinx extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 5;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyObject.java b/src/main/java/org/distorted/objects/TwistyObject.java
index 5367c7f2..da9c905a 100644
--- a/src/main/java/org/distorted/objects/TwistyObject.java
+++ b/src/main/java/org/distorted/objects/TwistyObject.java
@@ -370,13 +370,13 @@ public abstract class TwistyObject extends DistortedNode
       {
       Static4D quat;
       int index, axis, rowBitmap, angle;
-      int corr = (360/getBasicAngle());
+      int[] basic = getBasicAngle();
 
       for(int[] move: moves)
         {
         axis     = move[0];
         rowBitmap= move[1];
-        angle    = move[2]*corr;
+        angle    = move[2]*(360/basic[axis]);
         quat     = makeQuaternion(axis,angle);
 
         for(int j=0; j<NUM_CUBITS; j++)
@@ -914,9 +914,9 @@ public abstract class TwistyObject extends DistortedNode
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int computeNearestAngle(float angle, float speed)
+  public int computeNearestAngle(int axis, float angle, float speed)
     {
-    final int NEAREST = 360/getBasicAngle();
+    final int NEAREST = 360/getBasicAngle()[axis];
 
     int tmp = (int)((angle+NEAREST/2)/NEAREST);
     if( angle< -(NEAREST*0.5) ) tmp-=1;
@@ -961,10 +961,10 @@ public abstract class TwistyObject extends DistortedNode
   abstract float returnMultiplier();
   abstract float[] getCuts(int numLayers);
   abstract boolean shouldResetTextureMaps();
+  abstract Static3D[] getRotationAxis();
 
   public abstract boolean isSolved();
-  public abstract Static3D[] getRotationAxis();
-  public abstract int getBasicAngle();
+  public abstract int[] getBasicAngle();
   public abstract String retObjectString();
   public abstract void randomizeNewScramble(int[][] scramble, Random rnd, int numScramble);
   public abstract int getObjectName(int numLayers);
diff --git a/src/main/java/org/distorted/objects/TwistyPyraminx.java b/src/main/java/org/distorted/objects/TwistyPyraminx.java
index b76bc3d4..01ff16b7 100644
--- a/src/main/java/org/distorted/objects/TwistyPyraminx.java
+++ b/src/main/java/org/distorted/objects/TwistyPyraminx.java
@@ -47,6 +47,8 @@ public class TwistyPyraminx extends TwistyObject
            new Static3D(-SQ6/3,+SQ3/3,     0),
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_GREEN , COLOR_YELLOW,
@@ -377,9 +379,9 @@ public class TwistyPyraminx extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 3;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyRedi.java b/src/main/java/org/distorted/objects/TwistyRedi.java
index f17da7bf..dde131e0 100644
--- a/src/main/java/org/distorted/objects/TwistyRedi.java
+++ b/src/main/java/org/distorted/objects/TwistyRedi.java
@@ -51,6 +51,8 @@ public class TwistyRedi extends TwistyObject
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_YELLOW, COLOR_WHITE,
@@ -416,9 +418,9 @@ public class TwistyRedi extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 3;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyRex.java b/src/main/java/org/distorted/objects/TwistyRex.java
index a1bdecae..c624f13c 100644
--- a/src/main/java/org/distorted/objects/TwistyRex.java
+++ b/src/main/java/org/distorted/objects/TwistyRex.java
@@ -60,6 +60,8 @@ public class TwistyRex extends TwistyObject
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_YELLOW, COLOR_WHITE,
@@ -591,9 +593,9 @@ public class TwistyRex extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 3;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistySkewb.java b/src/main/java/org/distorted/objects/TwistySkewb.java
index d5d3d998..7ae06de1 100644
--- a/src/main/java/org/distorted/objects/TwistySkewb.java
+++ b/src/main/java/org/distorted/objects/TwistySkewb.java
@@ -51,6 +51,8 @@ public class TwistySkewb extends TwistyObject
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            COLOR_YELLOW, COLOR_WHITE,
@@ -611,9 +613,9 @@ public class TwistySkewb extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 3;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistySquare1.java b/src/main/java/org/distorted/objects/TwistySquare1.java
index 3267be9b..62be2877 100644
--- a/src/main/java/org/distorted/objects/TwistySquare1.java
+++ b/src/main/java/org/distorted/objects/TwistySquare1.java
@@ -50,6 +50,8 @@ class TwistySquare1 extends TwistyObject
       new Static3D(COS15,0,SIN15)
     };
 
+  private static final int[] BASIC_ANGLE = new int[] { 12,2 };
+
   private static final int[] FACE_COLORS = new int[]
     {
       COLOR_YELLOW, COLOR_WHITE,
@@ -454,11 +456,10 @@ class TwistySquare1 extends TwistyObject
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 4;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -472,7 +473,7 @@ class TwistySquare1 extends TwistyObject
       }
     else
       {
-      int newVector = rnd.nextInt(NUM_AXIS -1);
+      int newVector = rnd.nextInt(NUM_AXIS-1);
       scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
       }
 
diff --git a/src/main/java/org/distorted/objects/TwistyUltimate.java b/src/main/java/org/distorted/objects/TwistyUltimate.java
index b3c3a1c6..6841a9d4 100644
--- a/src/main/java/org/distorted/objects/TwistyUltimate.java
+++ b/src/main/java/org/distorted/objects/TwistyUltimate.java
@@ -69,6 +69,8 @@ class TwistyUltimate extends TwistyObject
            new Static3D( 0,C,-B)
          };
 
+  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
+
   private static final int[] FACE_COLORS = new int[]
          {
            MINX_LGREEN, MINX_PINK   , MINX_SANDY , MINX_LBLUE,
@@ -434,9 +436,9 @@ class TwistyUltimate extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getBasicAngle()
+  public int[] getBasicAngle()
     {
-    return 3;
+    return BASIC_ANGLE;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/patterns/RubikPattern.java b/src/main/java/org/distorted/patterns/RubikPattern.java
index a63514f1..cbe70a0c 100644
--- a/src/main/java/org/distorted/patterns/RubikPattern.java
+++ b/src/main/java/org/distorted/patterns/RubikPattern.java
@@ -265,11 +265,12 @@ public class RubikPattern
           }
         else
           {
-          int axis     = moves[curMove-1][0];
-		      int rowBitmap= moves[curMove-1][1];
-		      int bareAngle= moves[curMove-1][2];
-          int angle    = bareAngle*(360/pre.getObject().getBasicAngle());
-          int numRot   = Math.abs(bareAngle);
+          int axis      = moves[curMove-1][0];
+		      int rowBitmap = moves[curMove-1][1];
+		      int bareAngle = moves[curMove-1][2];
+		      int basicAngle= pre.getObject().getBasicAngle()[axis];
+          int angle     = bareAngle*(360/basicAngle);
+          int numRot    = Math.abs(bareAngle);
 
           if( angle!=0 )
             {
@@ -305,11 +306,12 @@ public class RubikPattern
           }
         else
           {
-          int axis     = moves[curMove][0];
-		      int rowBitmap= moves[curMove][1];
-		      int bareAngle= moves[curMove][2];
-          int angle    = bareAngle*(360/pre.getObject().getBasicAngle());
-          int numRot   = Math.abs(bareAngle);
+          int axis      = moves[curMove][0];
+		      int rowBitmap = moves[curMove][1];
+		      int bareAngle = moves[curMove][2];
+		      int basicAngle= pre.getObject().getBasicAngle()[axis];
+          int angle     = bareAngle*(360/basicAngle);
+          int numRot    = Math.abs(bareAngle);
 
           if( angle!=0 )
             {
diff --git a/src/main/java/org/distorted/screens/RubikScreenBase.java b/src/main/java/org/distorted/screens/RubikScreenBase.java
index ed3d164e..2c3b30cc 100644
--- a/src/main/java/org/distorted/screens/RubikScreenBase.java
+++ b/src/main/java/org/distorted/screens/RubikScreenBase.java
@@ -70,7 +70,8 @@ abstract class RubikScreenBase extends RubikScreenAbstract implements RubikPreRe
         int axis  = move.mAxis;
         int row   = (1<<move.mRow);
         int angle = move.mAngle;
-        int numRot= Math.abs(angle*object.getBasicAngle()/360);
+        int basic = object.getBasicAngle()[axis];
+        int numRot= Math.abs(angle*basic/360);
 
         if( angle!=0 )
           {
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolution.java b/src/main/java/org/distorted/screens/RubikScreenSolution.java
index 28375489..9b5ece51 100644
--- a/src/main/java/org/distorted/screens/RubikScreenSolution.java
+++ b/src/main/java/org/distorted/screens/RubikScreenSolution.java
@@ -197,11 +197,12 @@ public class RubikScreenSolution extends RubikScreenAbstract implements RubikPre
         }
       else
         {
-        int axis     = mMoves[mCurrMove-1][0];
-		    int rowBitmap= mMoves[mCurrMove-1][1];
-		    int bareAngle= mMoves[mCurrMove-1][2];
-        int angle    = bareAngle*(360/pre.getObject().getBasicAngle());
-        int numRot   = Math.abs(bareAngle);
+        int axis      = mMoves[mCurrMove-1][0];
+		    int rowBitmap = mMoves[mCurrMove-1][1];
+		    int bareAngle = mMoves[mCurrMove-1][2];
+		    int basicAngle= pre.getObject().getBasicAngle()[axis];
+        int angle     = bareAngle*(360/basicAngle);
+        int numRot    = Math.abs(bareAngle);
 
         if( angle!=0 )
           {
@@ -235,11 +236,12 @@ public class RubikScreenSolution extends RubikScreenAbstract implements RubikPre
         }
       else
         {
-        int axis     = mMoves[mCurrMove][0];
-		    int rowBitmap= mMoves[mCurrMove][1];
-		    int bareAngle= mMoves[mCurrMove][2];
-        int angle    = bareAngle*(360/pre.getObject().getBasicAngle());
-        int numRot   = Math.abs(bareAngle);
+        int axis      = mMoves[mCurrMove][0];
+		    int rowBitmap = mMoves[mCurrMove][1];
+		    int bareAngle = mMoves[mCurrMove][2];
+        int basicAngle= pre.getObject().getBasicAngle()[axis];
+        int angle     = bareAngle*(360/basicAngle);
+        int numRot    = Math.abs(bareAngle);
 
         if( angle!=0 )
           {
diff --git a/src/main/java/org/distorted/tutorials/TutorialState.java b/src/main/java/org/distorted/tutorials/TutorialState.java
index c58c23fd..79f476b8 100644
--- a/src/main/java/org/distorted/tutorials/TutorialState.java
+++ b/src/main/java/org/distorted/tutorials/TutorialState.java
@@ -74,7 +74,8 @@ public class TutorialState implements RubikPreRender.ActionFinishedListener
         int axis  = move.mAxis;
         int row   = (1<<move.mRow);
         int angle = move.mAngle;
-        int numRot= Math.abs(angle*object.getBasicAngle()/360);
+        int basic = object.getBasicAngle()[axis];
+        int numRot= Math.abs(angle*basic/360);
 
         if( angle!=0 )
           {
diff --git a/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java b/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
index b6f53b78..9d456ff2 100644
--- a/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
+++ b/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
@@ -366,7 +366,7 @@ public class TutorialSurfaceView extends GLSurfaceView
     private void finishRotation()
       {
       computeCurrentSpeedInInchesPerSecond();
-      int angle = mPreRender.getObject().computeNearestAngle(mCurrentAngle, mCurrRotSpeed);
+      int angle = mPreRender.getObject().computeNearestAngle(mCurrentAxis,mCurrentAngle, mCurrRotSpeed);
       mPreRender.finishRotation(angle);
 
       if( angle!=0 )
