Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / Movement12.java @ c7a98f94

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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 static org.distorted.objects.TwistyMinx.C2;
23
import static org.distorted.objects.TwistyMinx.COS54;
24
import static org.distorted.objects.TwistyMinx.LEN;
25
import static org.distorted.objects.TwistyMinx.SIN54;
26
import static org.distorted.objects.TwistyObject.SQ5;
27

    
28
import org.distorted.library.type.Static3D;
29

    
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31
// Dodecahedral objects: map the 2D swipes of user's fingers to 3D rotations
32

    
33
abstract class Movement12 extends Movement
34
{
35
  static final float DIST3D = (float)Math.sqrt(0.625f+0.275f*SQ5);
36
  static final float DIST2D = (SIN54/COS54)/2;
37

    
38
  static final Static3D[] FACE_AXIS = new Static3D[]
39
         {
40
           new Static3D(    C2/LEN, SIN54/LEN,    0      ),
41
           new Static3D(    C2/LEN,-SIN54/LEN,    0      ),
42
           new Static3D(   -C2/LEN, SIN54/LEN,    0      ),
43
           new Static3D(   -C2/LEN,-SIN54/LEN,    0      ),
44
           new Static3D( 0        ,    C2/LEN, SIN54/LEN ),
45
           new Static3D( 0        ,    C2/LEN,-SIN54/LEN ),
46
           new Static3D( 0        ,   -C2/LEN, SIN54/LEN ),
47
           new Static3D( 0        ,   -C2/LEN,-SIN54/LEN ),
48
           new Static3D( SIN54/LEN,    0     ,    C2/LEN ),
49
           new Static3D( SIN54/LEN,    0     ,   -C2/LEN ),
50
           new Static3D(-SIN54/LEN,    0     ,    C2/LEN ),
51
           new Static3D(-SIN54/LEN,    0     ,   -C2/LEN )
52
         };
53

    
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

    
56
  Movement12(Static3D[] rotAxis)
57
    {
58
    super(rotAxis, FACE_AXIS, DIST3D, DIST2D);
59
    }
60

    
61
///////////////////////////////////////////////////////////////////////////////////////////////////
62

    
63
  public float returnRotationFactor(int numLayers, int row)
64
    {
65
    return 1.0f;
66
    }
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69
// return angle (in radians) that the line connecting the center C of the pentagonal face and the
70
// first vertex of the pentagon makes with a vertical line coming upwards from the center C.
71

    
72
  private float returnAngle(int face)
73
    {
74
    switch(face)
75
      {
76
      case  0:
77
      case  2:
78
      case  6:
79
      case  7: return 0.0f;
80
      case  1:
81
      case  3:
82
      case  4:
83
      case  5: return (float)(36*Math.PI/180);
84
      case  9:
85
      case 10: return (float)(54*Math.PI/180);
86
      case  8:
87
      case 11: return (float)(18*Math.PI/180);
88
      }
89

    
90
    return 0.0f;
91
    }
92

    
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94
// The pair (distance,angle) defines a point P in R^2 in polar coordinate system. Let V be the vector
95
// from the center of the coordinate system to P.
96
// Let P' be the point defined by polar (distance,angle+PI/2). Let Lh be the half-line starting at
97
// P' and going in the direction of V.
98
// Return true iff point 'point' lies on the left of Lh, i.e. when we rotate (using the center of
99
// the coordinate system as the center of rotation) 'point' and Lh in such a way that Lh points
100
// directly upwards, is 'point' on the left or the right of it?
101

    
102
  private boolean isOnTheLeft(float[] point, float distance, float angle)
103
    {
104
    float sin = (float)Math.sin(angle);
105
    float cos = (float)Math.cos(angle);
106

    
107
    float vx = point[0] + sin*distance;
108
    float vy = point[1] - cos*distance;
109

    
110
    return vx*sin < vy*cos;
111
    }
112

    
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114
// Return 1,2,3,4,5 - the vertex of the pentagon to which point 'point' is the closest, if the
115
// 'point' is inside the pentagon - or 0 otherwise.
116
// The 'first' vertex is the one we meet the first when we rotate clockwise starting from 12:00.
117
// This vertex makes angle 'returnAngle()' with the line coming out upwards from the center of the
118
// pentagon.
119
// Distance from the center to a vertex of the pentagon = 1/(6*COS54)
120

    
121
  int returnPartOfThePentagon(float[] point, int face)
122
    {
123
    float angle = returnAngle(face);
124
    float A = (float)(Math.PI/5);
125

    
126
    for(int i=0; i<5; i++)
127
      {
128
      if( isOnTheLeft(point, DIST2D, (9-2*i)*A-angle) ) return 0;
129
      }
130

    
131
    if( isOnTheLeft(point, 0, 2.5f*A-angle) )
132
      {
133
      if( isOnTheLeft(point, 0, 3.5f*A-angle) )
134
        {
135
        return isOnTheLeft(point, 0, 5.5f*A-angle) ? 4 : 5;
136
        }
137
      else return 1;
138
      }
139
    else
140
      {
141
      if( isOnTheLeft(point, 0, 4.5f*A-angle) )
142
        {
143
        return 3;
144
        }
145
      else
146
        {
147
        return isOnTheLeft(point, 0, 6.5f*A-angle) ? 2 : 1;
148
        }
149
      }
150
    }
151

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

    
154
  boolean isInsideFace(int face, float[] p)
155
    {
156
    return returnPartOfThePentagon(p,face) > 0;
157
    }
158
}
(3-3/47)