Revision 7aa4c349
Added by Leszek Koltunski over 4 years ago
| src/main/java/org/distorted/control/RubikControl.java | ||
|---|---|---|
| 23 | 23 |
import org.distorted.library.main.DistortedNode; |
| 24 | 24 |
import org.distorted.library.main.DistortedScreen; |
| 25 | 25 |
import org.distorted.library.message.EffectListener; |
| 26 |
import org.distorted.library.type.Static4D; |
|
| 26 | 27 |
import org.distorted.main.RubikActivity; |
| 27 | 28 |
import org.distorted.main.RubikSurfaceView; |
| 28 | 29 |
import org.distorted.objects.TwistyObject; |
| ... | ... | |
| 57 | 58 |
return act!=null ? act.getObject() : null; |
| 58 | 59 |
} |
| 59 | 60 |
|
| 61 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 62 |
|
|
| 63 |
Static4D getCurrQuat() |
|
| 64 |
{
|
|
| 65 |
RubikActivity act = mRefAct.get(); |
|
| 66 |
return act!=null ? act.getCurrQuat() : null; |
|
| 67 |
} |
|
| 68 |
|
|
| 60 | 69 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 61 | 70 |
|
| 62 | 71 |
RubikSurfaceView getSurfaceView() |
| src/main/java/org/distorted/control/RubikControlRotate.java | ||
|---|---|---|
| 55 | 55 |
|
| 56 | 56 |
private void computeInitQuat() |
| 57 | 57 |
{
|
| 58 |
final double alphaZ = Math.PI/8; |
|
| 59 |
final double alphaY = Math.PI/16; |
|
| 58 |
double alphaZ = -Math.PI* 0.1250f; |
|
| 59 |
double alphaY = -Math.PI* 0.0625f; |
|
| 60 |
|
|
| 61 |
alphaY /= 2; |
|
| 62 |
alphaZ /= 2; |
|
| 60 | 63 |
|
| 61 | 64 |
float sinZ = (float)Math.sin(alphaZ); |
| 62 | 65 |
float cosZ = (float)Math.cos(alphaZ); |
| ... | ... | |
| 70 | 73 |
} |
| 71 | 74 |
|
| 72 | 75 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 76 |
// Take 3D vector 'ax', rotate it by quaternion 'objQuat' to get vector V1. |
|
| 77 |
// Take 3D vector (1,0,0) and rotate it by INIT_QUAT to get vector V2. |
|
| 78 |
// Return a quaternion Q such that if we rotate V1 by Q, we get V2. |
|
| 73 | 79 |
|
| 74 |
private Static4D computeQuat(Static3D ax) |
|
| 80 |
private Static4D computeQuat(Static3D ax, Static4D objQuat, float x, float y, float z)
|
|
| 75 | 81 |
{
|
| 76 |
return null; |
|
| 82 |
Static4D ax4D = new Static4D( ax.get0(), ax.get1(), ax.get2(), 0); |
|
| 83 |
Static4D axRo = QuatHelper.rotateVectorByQuat(ax4D,objQuat); |
|
| 84 |
return QuatHelper.retRotationQuat(axRo.get0(),axRo.get1(),axRo.get2(),x,y,z); |
|
| 77 | 85 |
} |
| 78 | 86 |
|
| 79 | 87 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 82 | 90 |
{
|
| 83 | 91 |
TwistyObject object = mControl.getObject(); |
| 84 | 92 |
Static3D[] axis = object.getRotationAxis(); |
| 93 |
int chosen=-1,numAxis = axis.length; |
|
| 85 | 94 |
float cos,maxCos = -1.0f; |
| 86 | 95 |
Static4D quat; |
| 87 | 96 |
|
| 88 |
for (Static3D axi : axis) |
|
| 97 |
Static4D objCurrQuat = mControl.getCurrQuat(); |
|
| 98 |
Static4D axisX = new Static4D(1,0,0,0); |
|
| 99 |
Static4D rotAxisX = QuatHelper.rotateVectorByQuat(axisX,INIT_QUAT); |
|
| 100 |
|
|
| 101 |
float axX = rotAxisX.get0(); |
|
| 102 |
float axY = rotAxisX.get1(); |
|
| 103 |
float axZ = rotAxisX.get2(); |
|
| 104 |
|
|
| 105 |
for (int a=0; a<numAxis; a++) |
|
| 89 | 106 |
{
|
| 90 |
quat = computeQuat(axi); |
|
| 107 |
quat = computeQuat(axis[a],objCurrQuat,axX,axY,axZ);
|
|
| 91 | 108 |
cos = quat.get3(); |
| 92 | 109 |
|
| 93 | 110 |
if (cos > maxCos) |
| 94 | 111 |
{
|
| 95 | 112 |
maxCos = cos; |
| 113 |
chosen = a; |
|
| 96 | 114 |
mObjRotQuat = quat; |
| 97 | 115 |
} |
| 98 | 116 |
} |
| 117 |
|
|
| 118 |
android.util.Log.e("D", "axis chosen: "+chosen);
|
|
| 99 | 119 |
} |
| 100 | 120 |
|
| 101 | 121 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 110 | 130 |
|
| 111 | 131 |
private void setObjectEffectsStage1() |
| 112 | 132 |
{
|
| 113 |
// TODO |
|
| 133 |
mDynamic.resetToBeginning(); |
|
| 134 |
mScale.notifyWhenFinished(mControl); |
|
| 114 | 135 |
} |
| 115 | 136 |
|
| 116 | 137 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 186 | 207 |
mObjectQuad = new MeshQuad(); |
| 187 | 208 |
} |
| 188 | 209 |
|
| 189 |
if( INIT_QUAT==null ) |
|
| 190 |
{
|
|
| 191 |
computeInitQuat(); |
|
| 192 |
computeRotQuat(); |
|
| 193 |
} |
|
| 210 |
if( INIT_QUAT==null ) computeInitQuat(); |
|
| 211 |
|
|
| 212 |
computeRotQuat(); |
|
| 194 | 213 |
|
| 195 | 214 |
DistortedTexture texture = new DistortedTexture(); |
| 196 | 215 |
texture.setColorARGB(0xff00ff00); |
| src/main/java/org/distorted/helpers/FactoryCubit.java | ||
|---|---|---|
| 368 | 368 |
return ft; |
| 369 | 369 |
} |
| 370 | 370 |
|
| 371 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 372 |
|
|
| 373 |
private double computeCos(double oldX, double oldY, double newX, double newY, double len1, double len2) |
|
| 374 |
{
|
|
| 375 |
double ret= (oldX*newX+oldY*newY) / (len1*len2); |
|
| 376 |
if( ret<-1.0 ) return -1.0; |
|
| 377 |
if( ret> 1.0 ) return 1.0; |
|
| 378 |
|
|
| 379 |
return ret; |
|
| 380 |
} |
|
| 381 |
|
|
| 382 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 383 |
// sin of (signed!) angle between vectors 'old' and 'new', counterclockwise! |
|
| 384 |
|
|
| 385 |
private double computeSin(double oldX, double oldY, double newX, double newY, double len1, double len2) |
|
| 386 |
{
|
|
| 387 |
double ret= (newX*oldY-oldX*newY) / (len1*len2); |
|
| 388 |
if( ret<-1.0 ) return -1.0; |
|
| 389 |
if( ret> 1.0 ) return 1.0; |
|
| 390 |
|
|
| 391 |
return ret; |
|
| 392 |
} |
|
| 393 |
|
|
| 394 | 371 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 395 | 372 |
|
| 396 | 373 |
private void rotateAllVertices(double[] result, int len, double[] vertices, double sin, double cos) |
| ... | ... | |
| 550 | 527 |
double newX = newVert[2*vertex ]; |
| 551 | 528 |
double newY = newVert[2*vertex+1]; |
| 552 | 529 |
double lenIthNew = Math.sqrt(newX*newX + newY*newY); |
| 553 |
double cos = computeCos( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld); |
|
| 554 |
double sin = computeSin( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld); |
|
| 530 |
double cos = QuatHelper.computeCos( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld);
|
|
| 531 |
double sin = QuatHelper.computeSin( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld);
|
|
| 555 | 532 |
|
| 556 | 533 |
rotateAllVertices(buffer,len,newVert,sin,cos); |
| 557 | 534 |
|
| src/main/java/org/distorted/helpers/QuatHelper.java | ||
|---|---|---|
| 28 | 28 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 29 | 29 |
// return quat1*quat2 |
| 30 | 30 |
|
| 31 |
public static Static4D quatMultiply( Static4D quat1, Static4D quat2 )
|
|
| 32 |
{
|
|
| 33 |
float qx = quat1.get0();
|
|
| 34 |
float qy = quat1.get1();
|
|
| 35 |
float qz = quat1.get2();
|
|
| 36 |
float qw = quat1.get3();
|
|
| 37 |
|
|
| 38 |
float rx = quat2.get0();
|
|
| 39 |
float ry = quat2.get1();
|
|
| 40 |
float rz = quat2.get2();
|
|
| 41 |
float rw = quat2.get3();
|
|
| 42 |
|
|
| 43 |
float tx = rw*qx - rz*qy + ry*qz + rx*qw;
|
|
| 44 |
float ty = rw*qy + rz*qx + ry*qw - rx*qz;
|
|
| 45 |
float tz = rw*qz + rz*qw - ry*qx + rx*qy;
|
|
| 46 |
float tw = rw*qw - rz*qz - ry*qy - rx*qx;
|
|
| 47 |
|
|
| 48 |
return new Static4D(tx,ty,tz,tw);
|
|
| 49 |
}
|
|
| 31 |
public static Static4D quatMultiply( Static4D quat1, Static4D quat2 ) |
|
| 32 |
{
|
|
| 33 |
float qx = quat1.get0(); |
|
| 34 |
float qy = quat1.get1(); |
|
| 35 |
float qz = quat1.get2(); |
|
| 36 |
float qw = quat1.get3(); |
|
| 37 |
|
|
| 38 |
float rx = quat2.get0(); |
|
| 39 |
float ry = quat2.get1(); |
|
| 40 |
float rz = quat2.get2(); |
|
| 41 |
float rw = quat2.get3(); |
|
| 42 |
|
|
| 43 |
float tx = rw*qx - rz*qy + ry*qz + rx*qw; |
|
| 44 |
float ty = rw*qy + rz*qx + ry*qw - rx*qz; |
|
| 45 |
float tz = rw*qz + rz*qw - ry*qx + rx*qy; |
|
| 46 |
float tw = rw*qw - rz*qz - ry*qy - rx*qx; |
|
| 47 |
|
|
| 48 |
return new Static4D(tx,ty,tz,tw); |
|
| 49 |
} |
|
| 50 | 50 |
|
| 51 | 51 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 52 | 52 |
// rotate 'vector' by quat ( i.e. return quat*vector*(quat^-1) ) |
| 53 | 53 |
|
| 54 |
public static Static4D rotateVectorByQuat(Static4D vector, Static4D quat)
|
|
| 55 |
{
|
|
| 56 |
float qx = quat.get0();
|
|
| 57 |
float qy = quat.get1();
|
|
| 58 |
float qz = quat.get2();
|
|
| 59 |
float qw = quat.get3();
|
|
| 54 |
public static Static4D rotateVectorByQuat(Static4D vector, Static4D quat) |
|
| 55 |
{
|
|
| 56 |
float qx = quat.get0(); |
|
| 57 |
float qy = quat.get1(); |
|
| 58 |
float qz = quat.get2(); |
|
| 59 |
float qw = quat.get3(); |
|
| 60 | 60 |
|
| 61 |
Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
|
|
| 62 |
Static4D tmp = quatMultiply(quat,vector);
|
|
| 61 |
Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw); |
|
| 62 |
Static4D tmp = quatMultiply(quat,vector); |
|
| 63 | 63 |
|
| 64 |
return quatMultiply(tmp,quatInverted);
|
|
| 65 |
}
|
|
| 64 |
return quatMultiply(tmp,quatInverted); |
|
| 65 |
} |
|
| 66 | 66 |
|
| 67 | 67 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 68 | 68 |
// rotate 'vector' by quat^(-1) ( i.e. return (quat^-1)*vector*quat ) |
| 69 | 69 |
|
| 70 |
public static Static4D rotateVectorByInvertedQuat(Static4D vector, Static4D quat) |
|
| 70 |
public static Static4D rotateVectorByInvertedQuat(Static4D vector, Static4D quat) |
|
| 71 |
{
|
|
| 72 |
float qx = quat.get0(); |
|
| 73 |
float qy = quat.get1(); |
|
| 74 |
float qz = quat.get2(); |
|
| 75 |
float qw = quat.get3(); |
|
| 76 |
|
|
| 77 |
Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw); |
|
| 78 |
Static4D tmp = quatMultiply(quatInverted,vector); |
|
| 79 |
|
|
| 80 |
return quatMultiply(tmp,quat); |
|
| 81 |
} |
|
| 82 |
|
|
| 83 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 84 |
|
|
| 85 |
public static Static4D quatFromDrag(float dragX, float dragY) |
|
| 86 |
{
|
|
| 87 |
float axisX = dragY; // inverted X and Y - rotation axis is perpendicular to (dragX,dragY) |
|
| 88 |
float axisY = dragX; // Why not (-dragY, dragX) ? because Y axis is also inverted! |
|
| 89 |
float axisZ = 0; |
|
| 90 |
float axisL = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ); |
|
| 91 |
|
|
| 92 |
if( axisL>0 ) |
|
| 71 | 93 |
{
|
| 72 |
float qx = quat.get0(); |
|
| 73 |
float qy = quat.get1(); |
|
| 74 |
float qz = quat.get2(); |
|
| 75 |
float qw = quat.get3(); |
|
| 94 |
axisX /= axisL; |
|
| 95 |
axisY /= axisL; |
|
| 96 |
axisZ /= axisL; |
|
| 97 |
|
|
| 98 |
float ratio = axisL; |
|
| 99 |
ratio = ratio - (int)ratio; // the cos() is only valid in (0,Pi) |
|
| 76 | 100 |
|
| 77 |
Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
|
|
| 78 |
Static4D tmp = quatMultiply(quatInverted,vector);
|
|
| 101 |
float cosA = (float)Math.cos(Math.PI*ratio);
|
|
| 102 |
float sinA = (float)Math.sqrt(1-cosA*cosA);
|
|
| 79 | 103 |
|
| 80 |
return quatMultiply(tmp,quat);
|
|
| 104 |
return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
|
|
| 81 | 105 |
} |
| 82 | 106 |
|
| 107 |
return new Static4D(0f, 0f, 0f, 1f); |
|
| 108 |
} |
|
| 109 |
|
|
| 83 | 110 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 84 | 111 |
|
| 85 |
public static Static4D quatFromDrag(float dragX, float dragY) |
|
| 86 |
{
|
|
| 87 |
float axisX = dragY; // inverted X and Y - rotation axis is perpendicular to (dragX,dragY) |
|
| 88 |
float axisY = dragX; // Why not (-dragY, dragX) ? because Y axis is also inverted! |
|
| 89 |
float axisZ = 0; |
|
| 90 |
float axisL = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ); |
|
| 112 |
public static double computeCos(double oldX, double oldY, double newX, double newY, double len1, double len2) |
|
| 113 |
{
|
|
| 114 |
double ret= (oldX*newX+oldY*newY) / (len1*len2); |
|
| 115 |
if( ret<-1.0 ) return -1.0; |
|
| 116 |
if( ret> 1.0 ) return 1.0; |
|
| 117 |
|
|
| 118 |
return ret; |
|
| 119 |
} |
|
| 120 |
|
|
| 121 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 122 |
// sin of (signed!) angle between vectors 'old' and 'new', counterclockwise! |
|
| 91 | 123 |
|
| 92 |
if( axisL>0 )
|
|
| 93 |
{
|
|
| 94 |
axisX /= axisL;
|
|
| 95 |
axisY /= axisL;
|
|
| 96 |
axisZ /= axisL;
|
|
| 124 |
public static double computeSin(double oldX, double oldY, double newX, double newY, double len1, double len2)
|
|
| 125 |
{
|
|
| 126 |
double ret= (newX*oldY-oldX*newY) / (len1*len2);
|
|
| 127 |
if( ret<-1.0 ) return -1.0;
|
|
| 128 |
if( ret> 1.0 ) return 1.0;
|
|
| 97 | 129 |
|
| 98 |
float ratio = axisL;
|
|
| 99 |
ratio = ratio - (int)ratio; // the cos() is only valid in (0,Pi)
|
|
| 130 |
return ret;
|
|
| 131 |
}
|
|
| 100 | 132 |
|
| 101 |
float cosA = (float)Math.cos(Math.PI*ratio); |
|
| 102 |
float sinA = (float)Math.sqrt(1-cosA*cosA); |
|
| 133 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 134 |
// return quat Q that turns 3D vector A=(ax,ay,az) to another 3D vector B=(bx,by,bz) |
|
| 135 |
// take care of double-cover by ensuring that always Q.get3() >=0 |
|
| 136 |
|
|
| 137 |
public static Static4D retRotationQuat(float ax, float ay, float az, float bx, float by, float bz) |
|
| 138 |
{
|
|
| 139 |
float nx = ay*bz - az*by; |
|
| 140 |
float ny = az*bx - ax*bz; |
|
| 141 |
float nz = ax*by - ay*bx; |
|
| 103 | 142 |
|
| 104 |
return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
|
|
| 105 |
}
|
|
| 143 |
float sin = (float)Math.sqrt(nx*nx + ny*ny + nz*nz);
|
|
| 144 |
float cos = ax*bx + ay*by + az*bz;
|
|
| 106 | 145 |
|
| 107 |
return new Static4D(0f, 0f, 0f, 1f); |
|
| 146 |
if( sin!=0 ) |
|
| 147 |
{
|
|
| 148 |
nx /= sin; |
|
| 149 |
ny /= sin; |
|
| 150 |
nz /= sin; |
|
| 108 | 151 |
} |
| 152 |
|
|
| 153 |
// Why sin<=0 and cos>=0 ? |
|
| 154 |
// 0<angle<180 -> 0<halfAngle<90 -> both sin and cos are positive. |
|
| 155 |
// But1: quats work counterclockwise -> negate cos. |
|
| 156 |
// But2: double-cover, we prefer to have the cos positive (so that unit=(0,0,0,1)) |
|
| 157 |
// so negate again both cos and sin. |
|
| 158 |
float sinHalf =-(float)Math.sqrt((1-cos)/2); |
|
| 159 |
float cosHalf = (float)Math.sqrt((1+cos)/2); |
|
| 160 |
|
|
| 161 |
return new Static4D(nx*sinHalf,ny*sinHalf,nz*sinHalf,cosHalf); |
|
| 162 |
} |
|
| 109 | 163 |
} |
| src/main/java/org/distorted/main/RubikActivity.java | ||
|---|---|---|
| 44 | 44 |
import org.distorted.library.main.DistortedLibrary; |
| 45 | 45 |
|
| 46 | 46 |
import org.distorted.library.main.DistortedScreen; |
| 47 |
import org.distorted.library.type.Static4D; |
|
| 47 | 48 |
import org.distorted.objects.TwistyObject; |
| 48 | 49 |
import org.distorted.network.RubikScores; |
| 49 | 50 |
import org.distorted.network.RubikNetwork; |
| ... | ... | |
| 602 | 603 |
play.setLockState(this); |
| 603 | 604 |
} |
| 604 | 605 |
|
| 606 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 607 |
|
|
| 608 |
public Static4D getCurrQuat() |
|
| 609 |
{
|
|
| 610 |
RubikSurfaceView view = findViewById(R.id.rubikSurfaceView); |
|
| 611 |
return view.getQuat(); |
|
| 612 |
} |
|
| 613 |
|
|
| 605 | 614 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 606 | 615 |
|
| 607 | 616 |
public void switchTutorial(String url, ObjectList object, int size) |
Also available in: Unified diff
Progress with RubikControl.