Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / main / Cubit.java @ 4135693b

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 TwistyObject mParent;
38

    
39
  int mQuatIndex;
40

    
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

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

    
49
    mOrigPosition    = new float[mLen];
50
    mCurrentPosition = new float[mLen];
51
    mTmp             = new float[4];
52

    
53
    for(int i=0; i<mLen; i++)
54
      {
55
      mOrigPosition[i]    = position[i];
56
      mCurrentPosition[i] = position[i];
57
      }
58

    
59
    mNumAxis     = numAxis;
60
    mRotationRow = new int[mNumAxis];
61
    computeRotationRow();
62
    }
63

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

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

    
84
    for(int q=0; q<num_quats; q++)
85
      {
86
      qt = mParent.mObjectQuats[q];
87

    
88
      xd = x - qt.get0();
89
      yd = y - qt.get1();
90
      zd = z - qt.get2();
91
      wd = w - qt.get3();
92

    
93
      diff = xd*xd + yd*yd + zd*zd + wd*wd;
94

    
95
      if( diff < mindiff )
96
        {
97
        ret = q;
98
        mindiff = diff;
99
        }
100

    
101
      xd = x + qt.get0();
102
      yd = y + qt.get1();
103
      zd = z + qt.get2();
104
      wd = w + qt.get3();
105

    
106
      diff = xd*xd + yd*yd + zd*zd + wd*wd;
107

    
108
      if( diff < mindiff )
109
        {
110
        ret = q;
111
        mindiff = diff;
112
        }
113
      }
114

    
115
    return ret;
116
    }
117

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

    
120
  private void computeRotationRow()
121
    {
122
    for(int i=0; i<mNumAxis; i++)
123
      {
124
      mRotationRow[i] = mParent.computeRow(mCurrentPosition,i);
125
      }
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  void modifyCurrentPosition(Static4D quat)
131
    {
132
    int len = mLen/3;
133

    
134
    for(int i=0; i<len; i++)
135
      {
136
      QuatHelper.rotateVectorByQuat( mTmp, mCurrentPosition[3*i], mCurrentPosition[3*i+1], mCurrentPosition[3*i+2], 0, quat);
137

    
138
      mCurrentPosition[3*i  ] = mTmp[0];
139
      mCurrentPosition[3*i+1] = mTmp[1];
140
      mCurrentPosition[3*i+2] = mTmp[2];
141

    
142
      mParent.clampPos(mCurrentPosition, 3*i);
143
      }
144

    
145
    computeRotationRow();
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  int computeAssociation()
151
    {
152
    int result = 0, accumulativeShift = 0;
153

    
154
    for(int axis=0; axis<mNumAxis; axis++)
155
      {
156
      result += (mRotationRow[axis]<<accumulativeShift);
157
      accumulativeShift += mParent.mMaxNumLayers;
158
      }
159

    
160
    return result;
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  void savePreferences(String key, SharedPreferences.Editor editor)
166
    {
167
    String k = key+"_"+mOrigPosition[0]+"_"+mOrigPosition[1]+"_"+mOrigPosition[2];
168
    editor.putInt(k, mQuatIndex);
169
    }
170

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

    
173
  void removePreferences(String key, SharedPreferences.Editor editor)
174
    {
175
    String k = key+"_"+mOrigPosition[0]+"_"+mOrigPosition[1]+"_"+mOrigPosition[2];
176
    editor.remove(k);
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

    
181
  int restorePreferences(String key, SharedPreferences preferences)
182
    {
183
    String k = key+"_"+mOrigPosition[0]+"_"+mOrigPosition[1]+"_"+mOrigPosition[2];
184
    mQuatIndex = preferences.getInt(k, 0);
185
    return mQuatIndex;
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

    
190
  int removeRotationNow(Static4D quat)
191
    {
192
    Static4D q = QuatHelper.quatMultiply(quat,mParent.mObjectQuats[mQuatIndex]);
193
    mQuatIndex = normalizeScrambleQuat(q);
194

    
195
    modifyCurrentPosition(quat);
196

    
197
    return mQuatIndex;
198
    }
199

    
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

    
202
  void solve()
203
    {
204
    mQuatIndex = 0;
205
    System.arraycopy(mOrigPosition, 0, mCurrentPosition, 0, mCurrentPosition.length);
206
    computeRotationRow();
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

    
211
  void releaseResources()
212
    {
213
    mParent = null;
214
    }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

    
218
  public int getRotRow(int axisIndex)
219
    {
220
    return mRotationRow[axisIndex];
221
    }
222
}
(1-1/12)