Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / main / Cubit.java @ 8005e762

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[] mOrigPosition;
32
  private final float[] mCurrentPosition;
33
  private final int mNumAxis;
34
  private final int mLen;
35
  private final int[] mRotationRow;
36
  private TwistyObject mParent;
37

    
38
  int mQuatIndex;
39

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

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

    
48
    mOrigPosition    = new float[mLen];
49
    mCurrentPosition = new float[mLen];
50

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

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

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

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

    
82
    for(int q=0; q<num_quats; q++)
83
      {
84
      qt = mParent.OBJECT_QUATS[q];
85

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

    
91
      diff = xd*xd + yd*yd + zd*zd + wd*wd;
92

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

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

    
104
      diff = xd*xd + yd*yd + zd*zd + wd*wd;
105

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

    
113
    return ret;
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

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

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

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

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

    
139
      mCurrentPosition[3*i  ] = rotatedCenter.get0();
140
      mCurrentPosition[3*i+1] = rotatedCenter.get1();
141
      mCurrentPosition[3*i+2] = rotatedCenter.get2();
142

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

    
146
    computeRotationRow();
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

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

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

    
161
    return result;
162
    }
163

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

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

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  int restorePreferences(SharedPreferences preferences)
175
    {
176
    String number = mOrigPosition[0]+"_"+mOrigPosition[1]+"_"+mOrigPosition[2];
177
    mQuatIndex = preferences.getInt("q_"+number, 0);
178
    return mQuatIndex;
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

    
183
  int removeRotationNow(Static4D quat)
184
    {
185
    Static4D q = QuatHelper.quatMultiply(quat,mParent.OBJECT_QUATS[mQuatIndex]);
186
    mQuatIndex = normalizeScrambleQuat(q);
187

    
188
    modifyCurrentPosition(quat);
189

    
190
    return mQuatIndex;
191
    }
192

    
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

    
195
  void solve()
196
    {
197
    mQuatIndex = 0;
198
    System.arraycopy(mOrigPosition, 0, mCurrentPosition, 0, mCurrentPosition.length);
199
    computeRotationRow();
200
    }
201

    
202
///////////////////////////////////////////////////////////////////////////////////////////////////
203

    
204
  void releaseResources()
205
    {
206
    mParent = null;
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
// this is only needed for MODE_REPLACE objects (i.e. - currently - CUBE_3), so it is enough to only
211
// take into consideration the first position.
212

    
213
  float getDistSquared(float[] point)
214
    {
215
    float dx = mCurrentPosition[0] - point[0];
216
    float dy = mCurrentPosition[1] - point[1];
217
    float dz = mCurrentPosition[2] - point[2];
218

    
219
    return dx*dx + dy*dy + dz*dz;
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
  public int getRotRow(int index)
225
    {
226
    return mRotationRow[index];
227
    }
228
}
(1-1/20)