Project

General

Profile

« Previous | Next » 

Revision 9f4c44fe

Added by Leszek Koltunski about 4 years ago

Progress with the Pyraminx - computing all legal quaternions!

View differences:

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