Revision 9f4c44fe
Added by Leszek Koltunski over 5 years ago
| src/main/java/org/distorted/object/Cubit.java | ||
|---|---|---|
| 65 | 65 |
|
| 66 | 66 |
private void normalizeScrambleQuat(Static4D quat) |
| 67 | 67 |
{
|
| 68 |
final float MAX_ERROR = 0.0001f; |
|
| 69 |
|
|
| 68 | 70 |
float x = quat.get0(); |
| 69 | 71 |
float y = quat.get1(); |
| 70 | 72 |
float z = quat.get2(); |
| ... | ... | |
| 74 | 76 |
for(float legal: mParent.LEGAL_QUATS) |
| 75 | 77 |
{
|
| 76 | 78 |
diff = x-legal; |
| 77 |
if( diff*diff<0.01f ) x = legal;
|
|
| 79 |
if( diff*diff<MAX_ERROR ) x = legal;
|
|
| 78 | 80 |
diff = y-legal; |
| 79 |
if( diff*diff<0.01f ) y = legal;
|
|
| 81 |
if( diff*diff<MAX_ERROR ) y = legal;
|
|
| 80 | 82 |
diff = z-legal; |
| 81 |
if( diff*diff<0.01f ) z = legal;
|
|
| 83 |
if( diff*diff<MAX_ERROR ) z = legal;
|
|
| 82 | 84 |
diff = w-legal; |
| 83 |
if( diff*diff<0.01f ) w = legal;
|
|
| 85 |
if( diff*diff<MAX_ERROR ) w = legal;
|
|
| 84 | 86 |
} |
| 85 | 87 |
|
| 86 | 88 |
if( w<0 ) |
| src/main/java/org/distorted/object/RubikCube.java | ||
|---|---|---|
| 62 | 62 |
// multiplying them and eventually you'll find all (24) legal rotations. |
| 63 | 63 |
// 3) linear scan through those shows that the only floats in those 24 quats are those 7 given |
| 64 | 64 |
// below. |
| 65 |
// |
|
| 66 |
// Example program in C, res/raw/compute_quats.c , is included. |
|
| 65 | 67 |
private static final float[] LEGALQUATS = new float[] |
| 66 | 68 |
{
|
| 67 | 69 |
0.0f , |
| src/main/java/org/distorted/object/RubikPyraminx.java | ||
|---|---|---|
| 40 | 40 |
|
| 41 | 41 |
public class RubikPyraminx extends RubikObject |
| 42 | 42 |
{
|
| 43 |
private static final float SQ2 = (float)Math.sqrt(2); |
|
| 44 |
private static final float SQ3 = (float)Math.sqrt(3); |
|
| 45 |
|
|
| 43 | 46 |
private static final Static3D[] AXIS = new Static3D[] |
| 44 | 47 |
{
|
| 45 |
new Static3D( 0, 1, 0 ),
|
|
| 46 |
new Static3D( (float)Math.sqrt(6)/3, -1.0f/3, -(float)Math.sqrt(3)/3 ),
|
|
| 47 |
new Static3D(-(float)Math.sqrt(6)/3, -1.0f/3, -(float)Math.sqrt(3)/3 ),
|
|
| 48 |
new Static3D( 0, -1.0f/3, 2*(float)Math.sqrt(2)/3 )
|
|
| 48 |
new Static3D( 0, 1, 0 ),
|
|
| 49 |
new Static3D( SQ2*SQ3/3, -1.0f/3, -SQ2/3 ),
|
|
| 50 |
new Static3D(-SQ2*SQ3/3, -1.0f/3, -SQ2/3 ),
|
|
| 51 |
new Static3D( 0, -1.0f/3, 2*SQ2/3 )
|
|
| 49 | 52 |
}; |
| 50 | 53 |
|
| 51 | 54 |
private static final int[] FACE_COLORS = new int[] |
| ... | ... | |
| 54 | 57 |
0xff0000ff, 0xffff0000 // AXIS[2]right (BLUE ) AXIS[3]right (RED ) |
| 55 | 58 |
}; |
| 56 | 59 |
|
| 60 |
// computed with res/raw/compute_quats.c |
|
| 57 | 61 |
private static final float[] LEGALQUATS = new float[] |
| 58 | 62 |
{
|
| 59 |
// TODO; |
|
| 63 |
0.0f, 1.0f, -1.0f, 0.5f, -0.5f, SQ2/2, -SQ2/2, SQ3/2, -SQ3/2, |
|
| 64 |
SQ3/3, -SQ3/3, SQ3/6, -SQ3/6, SQ2*SQ3/3, -SQ2*SQ3/3, SQ2*SQ3/6, -SQ2*SQ3/6 |
|
| 60 | 65 |
}; |
| 61 | 66 |
|
| 62 | 67 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 106 | 111 |
|
| 107 | 112 |
MeshBase createCubitMesh(int vertices) |
| 108 | 113 |
{
|
| 109 |
final float SQ3 = (float)Math.sqrt(3); |
|
| 110 | 114 |
final float angleFaces = (float)((180/Math.PI)*(2*Math.asin(SQ3/3))); // angle between two faces of a tetrahedron |
| 111 | 115 |
final int MESHES=4; |
| 112 | 116 |
|
| src/main/res/raw/compute_quats.c | ||
|---|---|---|
| 1 |
#include <stdio.h> |
|
| 2 |
#include <math.h> |
|
| 3 |
#include <stdlib.h> |
|
| 4 |
|
|
| 5 |
#define PYRAMIX |
|
| 6 |
|
|
| 7 |
#define SQ2 1.41421356237f |
|
| 8 |
#define SQ3 1.73205080757f |
|
| 9 |
#define PI 3.14159265358f |
|
| 10 |
#define NUM_QUATS 100 |
|
| 11 |
|
|
| 12 |
#ifdef PYRAMIX |
|
| 13 |
#define NUM_AXIS 4 |
|
| 14 |
#define BASIC_ANGLE 3 |
|
| 15 |
|
|
| 16 |
float axis[NUM_AXIS][3] ={ { 0, 1, 0 } ,
|
|
| 17 |
{ SQ2*SQ3/3, -1.0f/3, -SQ2/3 } ,
|
|
| 18 |
{-SQ2*SQ3/3, -1.0f/3, -SQ2/3 } ,
|
|
| 19 |
{ 0, -1.0f/3, 2*SQ2/3 } };
|
|
| 20 |
#endif |
|
| 21 |
|
|
| 22 |
#ifdef CUBE |
|
| 23 |
#define NUM_AXIS 3 |
|
| 24 |
#define BASIC_ANGLE 4 |
|
| 25 |
float axis[NUM_AXIS][3] = { { 1,0,0 }, {0,1,0}, {0,0,1} };
|
|
| 26 |
#endif |
|
| 27 |
|
|
| 28 |
float* quats; |
|
| 29 |
float* table; |
|
| 30 |
int inserted=0; |
|
| 31 |
|
|
| 32 |
/////////////////////////////////////////////////////////////////// |
|
| 33 |
// q1*q2 |
|
| 34 |
|
|
| 35 |
void multiply_quats( float* q1, float* q2, float* output) |
|
| 36 |
{
|
|
| 37 |
output[0] = q2[3]*q1[0] - q2[2]*q1[1] + q2[1]*q1[2] + q2[0]*q1[3]; |
|
| 38 |
output[1] = q2[3]*q1[1] + q2[2]*q1[0] + q2[1]*q1[3] - q2[0]*q1[2]; |
|
| 39 |
output[2] = q2[3]*q1[2] + q2[2]*q1[3] - q2[1]*q1[0] + q2[0]*q1[1]; |
|
| 40 |
output[3] = q2[3]*q1[3] - q2[2]*q1[2] - q2[1]*q1[1] - q2[0]*q1[0]; |
|
| 41 |
} |
|
| 42 |
|
|
| 43 |
/////////////////////////////////////////////////////////////////// |
|
| 44 |
// sin(A/2)*x, sin(A/2)*y, sin(A/2)*z, cos(A/2) |
|
| 45 |
|
|
| 46 |
void create_quat(float* axis, float angle, float* output) |
|
| 47 |
{
|
|
| 48 |
float cosAngle = cos(angle/2); |
|
| 49 |
float sinAngle = sin(angle/2); |
|
| 50 |
|
|
| 51 |
output[0] = sinAngle*axis[0]; |
|
| 52 |
output[1] = sinAngle*axis[1]; |
|
| 53 |
output[2] = sinAngle*axis[2]; |
|
| 54 |
output[3] = cosAngle; |
|
| 55 |
} |
|
| 56 |
|
|
| 57 |
/////////////////////////////////////////////////////////////////// |
|
| 58 |
// double cover, so q == -q |
|
| 59 |
|
|
| 60 |
int is_the_same(float* q1, float* q2) |
|
| 61 |
{
|
|
| 62 |
const float MAX = 0.01f; |
|
| 63 |
|
|
| 64 |
float d0 = q1[0]-q2[0]; |
|
| 65 |
float d1 = q1[1]-q2[1]; |
|
| 66 |
float d2 = q1[2]-q2[2]; |
|
| 67 |
float d3 = q1[3]-q2[3]; |
|
| 68 |
|
|
| 69 |
if( d0<MAX && d0>-MAX && |
|
| 70 |
d1<MAX && d1>-MAX && |
|
| 71 |
d2<MAX && d2>-MAX && |
|
| 72 |
d3<MAX && d3>-MAX ) return 1; |
|
| 73 |
|
|
| 74 |
d0 = q1[0]+q2[0]; |
|
| 75 |
d1 = q1[1]+q2[1]; |
|
| 76 |
d2 = q1[2]+q2[2]; |
|
| 77 |
d3 = q1[3]+q2[3]; |
|
| 78 |
|
|
| 79 |
if( d0<MAX && d0>-MAX && |
|
| 80 |
d1<MAX && d1>-MAX && |
|
| 81 |
d2<MAX && d2>-MAX && |
|
| 82 |
d3<MAX && d3>-MAX ) return 1; |
|
| 83 |
|
|
| 84 |
return 0; |
|
| 85 |
} |
|
| 86 |
|
|
| 87 |
/////////////////////////////////////////////////////////////////// |
|
| 88 |
|
|
| 89 |
void insert(float* quat, float* to) |
|
| 90 |
{
|
|
| 91 |
for(int i=0; i<inserted; i++) |
|
| 92 |
{
|
|
| 93 |
if( is_the_same(quat,to+4*i)==1 ) return; |
|
| 94 |
} |
|
| 95 |
|
|
| 96 |
to[4*inserted+0] = quat[0]; |
|
| 97 |
to[4*inserted+1] = quat[1]; |
|
| 98 |
to[4*inserted+2] = quat[2]; |
|
| 99 |
to[4*inserted+3] = quat[3]; |
|
| 100 |
|
|
| 101 |
inserted++; |
|
| 102 |
} |
|
| 103 |
|
|
| 104 |
/////////////////////////////////////////////////////////////////// |
|
| 105 |
|
|
| 106 |
int main(int argc, char** argv) |
|
| 107 |
{
|
|
| 108 |
float tmp[4]; |
|
| 109 |
int num = 1+NUM_AXIS*(BASIC_ANGLE-1); |
|
| 110 |
|
|
| 111 |
quats = (float*) malloc(4*sizeof(float)*num ); |
|
| 112 |
table = (float*) malloc(4*sizeof(float)*NUM_QUATS); |
|
| 113 |
|
|
| 114 |
tmp[0] = 0.0f; tmp[1] = 0.0f; tmp[2] = 0.0f; tmp[3] = 1.0f; |
|
| 115 |
insert(tmp,quats); |
|
| 116 |
|
|
| 117 |
for(int angle=1; angle<BASIC_ANGLE; angle++) |
|
| 118 |
for( int ax=0; ax<NUM_AXIS; ax++) |
|
| 119 |
{
|
|
| 120 |
create_quat(axis[ax], 2*PI*angle/BASIC_ANGLE, tmp); |
|
| 121 |
insert(tmp,quats); |
|
| 122 |
} |
|
| 123 |
|
|
| 124 |
inserted=0; |
|
| 125 |
|
|
| 126 |
for(int i=0; i<num; i++) |
|
| 127 |
for(int j=0; j<num; j++) |
|
| 128 |
{
|
|
| 129 |
multiply_quats( quats+4*i, quats+4*j, tmp); |
|
| 130 |
insert(tmp,table); |
|
| 131 |
} |
|
| 132 |
|
|
| 133 |
printf("inserted: %d\n", inserted);
|
|
| 134 |
|
|
| 135 |
for(int i=0; i<inserted; i++) |
|
| 136 |
{
|
|
| 137 |
printf( "%d %7.4f %7.4f %7.4f %7.4f\n", i, table[4*i], table[4*i+1], table[4*i+2], table[4*i+3] ); |
|
| 138 |
} |
|
| 139 |
|
|
| 140 |
return 0; |
|
| 141 |
} |
|
Also available in: Unified diff
Progress with the Pyraminx - computing all legal quaternions!