Project

General

Profile

Download (7.39 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / main / Cubit.java @ bc008758

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.objectlib.main;
21

    
22
import android.content.SharedPreferences;
23

    
24
import org.distorted.library.main.QuatHelper;
25
import org.distorted.library.type.Static4D;
26

    
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

    
29
public class Cubit
30
  {
31
  private final float[] mTmp;
32
  private final float[] mOrigPosition;
33
  private final float[] mCurrentPosition;
34
  private final int mNumAxis;
35
  private final int mLen;
36
  private final int[] mRotationRow;
37
  private final int mOrigCubitIndex;
38
  private int mCubitIndex;
39
  private TwistyObject mParent;
40

    
41
  int mQuatIndex;
42

    
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44

    
45
  Cubit(TwistyObject parent, float[] position, int numAxis, int cubitIndex)
46
    {
47
    mQuatIndex= 0;
48
    mParent   = parent;
49
    mLen      = position.length;
50

    
51
    mCubitIndex      = cubitIndex;
52
    mOrigCubitIndex  = cubitIndex;
53
    mOrigPosition    = new float[mLen];
54
    mCurrentPosition = new float[mLen];
55
    mTmp             = new float[4];
56

    
57
    for(int i=0; i<mLen; i++)
58
      {
59
      mOrigPosition[i]    = position[i];
60
      mCurrentPosition[i] = position[i];
61
      }
62

    
63
    mNumAxis     = numAxis;
64
    mRotationRow = new int[mNumAxis];
65
    computeRotationRow();
66
    }
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69
// Because of quatMultiplication, errors can accumulate - so to avoid this, we
70
// correct the value of the 'scramble' quat to what it should be - one of the legal quats from the
71
// list QUATS.
72
//
73
// We also have to remember that the group of unit quaternions is a double-cover of rotations
74
// in 3D ( q represents the same rotation as -q ) - so invert if needed.
75

    
76
  private int normalizeScrambleQuat(Static4D quat)
77
    {
78
    float x = quat.get0();
79
    float y = quat.get1();
80
    float z = quat.get2();
81
    float w = quat.get3();
82
    float xd,yd,zd,wd;
83
    float diff, mindiff = Float.MAX_VALUE;
84
    int ret=0;
85
    int num_quats = mParent.mObjectQuats.length;
86
    Static4D qt;
87

    
88
    for(int q=0; q<num_quats; q++)
89
      {
90
      qt = mParent.mObjectQuats[q];
91

    
92
      xd = x - qt.get0();
93
      yd = y - qt.get1();
94
      zd = z - qt.get2();
95
      wd = w - qt.get3();
96

    
97
      diff = xd*xd + yd*yd + zd*zd + wd*wd;
98

    
99
      if( diff < mindiff )
100
        {
101
        ret = q;
102
        mindiff = diff;
103
        }
104

    
105
      xd = x + qt.get0();
106
      yd = y + qt.get1();
107
      zd = z + qt.get2();
108
      wd = w + qt.get3();
109

    
110
      diff = xd*xd + yd*yd + zd*zd + wd*wd;
111

    
112
      if( diff < mindiff )
113
        {
114
        ret = q;
115
        mindiff = diff;
116
        }
117
      }
118

    
119
    return ret;
120
    }
121

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

    
124
  private void computeRotationRow()
125
    {
126
    for(int i=0; i<mNumAxis; i++)
127
      {
128
      mRotationRow[i] = mParent.computeRow(mCurrentPosition,i,mCubitIndex);
129
      }
130
    }
131

    
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

    
134
  void modifyCurrentPosition(Static4D quat)
135
    {
136
    int len = mLen/3;
137

    
138
    for(int i=0; i<len; i++)
139
      {
140
      QuatHelper.rotateVectorByQuat( mTmp, mCurrentPosition[3*i], mCurrentPosition[3*i+1], mCurrentPosition[3*i+2], 0, quat);
141

    
142
      mCurrentPosition[3*i  ] = mTmp[0];
143
      mCurrentPosition[3*i+1] = mTmp[1];
144
      mCurrentPosition[3*i+2] = mTmp[2];
145

    
146
      mCubitIndex = mParent.clampPos(mCurrentPosition, 3*i);
147
      }
148

    
149
    computeRotationRow();
150
    }
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

    
154
  int computeAssociation()
155
    {
156
    int result = 0, accumulativeShift = 0;
157

    
158
    for(int axis=0; axis<mNumAxis; axis++)
159
      {
160
      result += (mRotationRow[axis]<<accumulativeShift);
161
      accumulativeShift += mParent.mMaxNumLayers;
162
      }
163

    
164
    return result;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  void savePreferences(String key, SharedPreferences.Editor editor)
170
    {
171
    String k = key+"_"+mOrigPosition[0]+"_"+mOrigPosition[1]+"_"+mOrigPosition[2];
172
    editor.putInt(k, mQuatIndex);
173
    }
174

    
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176

    
177
  void removePreferences(String key, SharedPreferences.Editor editor)
178
    {
179
    String k = key+"_"+mOrigPosition[0]+"_"+mOrigPosition[1]+"_"+mOrigPosition[2];
180
    editor.remove(k);
181
    }
182

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

    
185
  int restorePreferences(String key, SharedPreferences preferences)
186
    {
187
    String k = key+"_"+mOrigPosition[0]+"_"+mOrigPosition[1]+"_"+mOrigPosition[2];
188
    mQuatIndex = preferences.getInt(k, 0);
189
    return mQuatIndex;
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  int removeRotationNow(Static4D quat)
195
    {
196
    Static4D q = QuatHelper.quatMultiply(quat,mParent.mObjectQuats[mQuatIndex]);
197
    mQuatIndex = normalizeScrambleQuat(q);
198

    
199
    modifyCurrentPosition(quat);
200

    
201
    return mQuatIndex;
202
    }
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

    
206
  void solve()
207
    {
208
    mQuatIndex = 0;
209
    mCubitIndex= mOrigCubitIndex;
210
    System.arraycopy(mOrigPosition, 0, mCurrentPosition, 0, mCurrentPosition.length);
211
    computeRotationRow();
212
    }
213

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

    
216
  void releaseResources()
217
    {
218
    mParent = null;
219
    }
220

    
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

    
223
  public int getRotRow(int axisIndex)
224
    {
225
    return mRotationRow[axisIndex];
226
    }
227
}
(1-1/13)