Project

General

Profile

Download (7.35 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / Cubit.java @ 54342a21

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objects;
21

    
22
import android.content.SharedPreferences;
23

    
24
import org.distorted.library.type.Static3D;
25
import org.distorted.library.type.Static4D;
26
import org.distorted.main.RubikSurfaceView;
27

    
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29

    
30
class Cubit
31
  {
32
  private final Static3D mOrigPosition;
33
  private final Static3D mCurrentPosition;
34
  private TwistyObject mParent;
35
  private final int mNumAxis;
36

    
37
  int mQuatIndex;
38
  int[] mRotationRow;
39

    
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

    
42
  Cubit(TwistyObject parent, Static3D position)
43
    {
44
    float x = position.get0();
45
    float y = position.get1();
46
    float z = position.get2();
47

    
48
    mParent          = parent;
49
    mOrigPosition    = new Static3D(x,y,z);
50
    mCurrentPosition = new Static3D(x,y,z);
51
    mQuatIndex       = 0;
52

    
53
    mNumAxis     = mParent.ROTATION_AXIS.length;
54
    mRotationRow = new int[mNumAxis];
55
    computeRotationRow();
56
    }
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59
// Because of quatMultiplication, errors can accumulate - so to avoid this, we
60
// correct the value of the 'scramble' quat to what it should be - one of the legal quats from the
61
// list QUATS.
62
//
63
// We also have to remember that the group of unit quaternions is a double-cover of rotations
64
// in 3D ( q represents the same rotation as -q ) - so invert if needed.
65

    
66
  private int normalizeScrambleQuat(Static4D quat)
67
    {
68
    float x = quat.get0();
69
    float y = quat.get1();
70
    float z = quat.get2();
71
    float w = quat.get3();
72
    float xd,yd,zd,wd;
73
    float diff, mindiff = Float.MAX_VALUE;
74
    int ret=0;
75
    int num_quats = mParent.QUATS.length;
76
    Static4D qt;
77

    
78
    for(int q=0; q<num_quats; q++)
79
      {
80
      qt = mParent.QUATS[q];
81

    
82
      xd = x - qt.get0();
83
      yd = y - qt.get1();
84
      zd = z - qt.get2();
85
      wd = w - qt.get3();
86

    
87
      diff = xd*xd + yd*yd + zd*zd + wd*wd;
88

    
89
      if( diff < mindiff )
90
        {
91
        ret = q;
92
        mindiff = diff;
93
        }
94

    
95
      xd = x + qt.get0();
96
      yd = y + qt.get1();
97
      zd = z + qt.get2();
98
      wd = w + qt.get3();
99

    
100
      diff = xd*xd + yd*yd + zd*zd + wd*wd;
101

    
102
      if( diff < mindiff )
103
        {
104
        ret = q;
105
        mindiff = diff;
106
        }
107
      }
108

    
109
    return ret;
110
    }
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

    
114
  private void computeRotationRow()
115
    {
116
    float x = mCurrentPosition.get0();
117
    float y = mCurrentPosition.get1();
118
    float z = mCurrentPosition.get2();
119

    
120
    for(int i=0; i<mNumAxis; i++)
121
      {
122
      mRotationRow[i] = mParent.computeRow(x,y,z,i);
123
      }
124
    }
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

    
128
  Static3D getOrigPosition()
129
    {
130
    return mOrigPosition;
131
    }
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  void modifyCurrentPosition(Static4D quat)
136
    {
137
    float cubitCenterX = mCurrentPosition.get0();
138
    float cubitCenterY = mCurrentPosition.get1();
139
    float cubitCenterZ = mCurrentPosition.get2();
140

    
141
    Static4D cubitCenter =  new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
142
    Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
143

    
144
    float rotatedX = rotatedCenter.get0();
145
    float rotatedY = rotatedCenter.get1();
146
    float rotatedZ = rotatedCenter.get2();
147

    
148
    mCurrentPosition.set(rotatedX, rotatedY, rotatedZ);
149
    mParent.clampPos(mCurrentPosition);
150

    
151
    computeRotationRow();
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

    
156
  int computeAssociation()
157
    {
158
    int result = 0, accumulativeShift = 0;
159

    
160
    for(int axis=0; axis<mNumAxis; axis++)
161
      {
162
      result += (1<<(mRotationRow[axis]+accumulativeShift));
163
      accumulativeShift += ObjectList.MAX_OBJECT_SIZE;
164
      }
165

    
166
    return result;
167
    }
168

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170

    
171
  void savePreferences(SharedPreferences.Editor editor)
172
    {
173
    String number = mOrigPosition.get0()+"_"+mOrigPosition.get1()+"_"+mOrigPosition.get2();
174
    editor.putInt("q_"+number, mQuatIndex);
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  int restorePreferences(SharedPreferences preferences)
180
    {
181
    String number = mOrigPosition.get0()+"_"+mOrigPosition.get1()+"_"+mOrigPosition.get2();
182
    mQuatIndex = preferences.getInt("q_"+number, 0);
183
    return mQuatIndex;
184
    }
185

    
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187

    
188
  int removeRotationNow(Static4D quat)
189
    {
190
    Static4D q = RubikSurfaceView.quatMultiply(quat,mParent.QUATS[mQuatIndex]);
191
    mQuatIndex = normalizeScrambleQuat(q);
192

    
193
    modifyCurrentPosition(quat);
194

    
195
    return mQuatIndex;
196
    }
197

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

    
200
  void solve()
201
    {
202
    mQuatIndex = 0;
203
    mCurrentPosition.set(mOrigPosition);
204
    computeRotationRow();
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  void releaseResources()
210
    {
211
    mParent = null;
212
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  float getDistSquared(float[] point)
217
    {
218
    float dx = mCurrentPosition.get0() - point[0];
219
    float dy = mCurrentPosition.get1() - point[1];
220
    float dz = mCurrentPosition.get2() - point[2];
221

    
222
    return dx*dx + dy*dy + dz*dz;
223
    }
224
}
(1-1/28)