Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / touchcontrol / TouchControlDodecahedron.java @ 1eafa9c6

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.touchcontrol;
11

    
12
import static org.distorted.objectlib.main.TwistyObject.SQ5;
13

    
14
import org.distorted.library.type.Static3D;
15
import org.distorted.objectlib.main.TwistyObject;
16

    
17
///////////////////////////////////////////////////////////////////////////////////////////////////
18
// Dodecahedral objects: map the 2D swipes of user's fingers to 3D rotations
19

    
20
public class TouchControlDodecahedron extends TouchControlShapeConstant
21
{
22
  public static final float C2       = (SQ5+3)/4;
23
  public static final float LEN      = (float)(Math.sqrt(1.25f+0.5f*SQ5));
24
  public static final float SIN54    = (SQ5+1)/4;
25
  public static final float COS54    = (float)(Math.sqrt(10-2*SQ5)/4);
26

    
27
  public static final float DIST3D  = (float)Math.sqrt(0.625f+0.275f*SQ5);
28
  public static final float DIST2D  = (SIN54/COS54)/2;
29
  public static final float[] D3D   = { DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,
30
                                        DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D };
31

    
32
  public static final Static3D[] FACE_AXIS = new Static3D[]
33
         {
34
           new Static3D(    C2/LEN, SIN54/LEN,    0      ),
35
           new Static3D(    C2/LEN,-SIN54/LEN,    0      ),
36
           new Static3D(   -C2/LEN, SIN54/LEN,    0      ),
37
           new Static3D(   -C2/LEN,-SIN54/LEN,    0      ),
38
           new Static3D( 0        ,    C2/LEN, SIN54/LEN ),
39
           new Static3D( 0        ,    C2/LEN,-SIN54/LEN ),
40
           new Static3D( 0        ,   -C2/LEN, SIN54/LEN ),
41
           new Static3D( 0        ,   -C2/LEN,-SIN54/LEN ),
42
           new Static3D( SIN54/LEN,    0     ,    C2/LEN ),
43
           new Static3D( SIN54/LEN,    0     ,   -C2/LEN ),
44
           new Static3D(-SIN54/LEN,    0     ,    C2/LEN ),
45
           new Static3D(-SIN54/LEN,    0     ,   -C2/LEN )
46
         };
47

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

    
50
  public TouchControlDodecahedron(TwistyObject object)
51
    {
52
    super(object,D3D,FACE_AXIS);
53
    }
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56
// return angle (in radians) that the line connecting the center C of the pentagonal face and the
57
// first vertex of the pentagon makes with a vertical line coming upwards from the center C.
58

    
59
  private float returnAngle(int face)
60
    {
61
    switch(face)
62
      {
63
      case  0:
64
      case  2:
65
      case  6:
66
      case  7: return 0.0f;
67
      case  1:
68
      case  3:
69
      case  4:
70
      case  5: return (float)(36*Math.PI/180);
71
      case  9:
72
      case 10: return (float)(54*Math.PI/180);
73
      case  8:
74
      case 11: return (float)(18*Math.PI/180);
75
      }
76

    
77
    return 0.0f;
78
    }
79

    
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81
// The pair (distance,angle) defines a point P in R^2 in polar coordinate system. Let V be the vector
82
// from the center of the coordinate system to P.
83
// Let P' be the point defined by polar (distance,angle+PI/2). Let Lh be the half-line starting at
84
// P' and going in the direction of V.
85
// Return true iff point 'point' lies on the left of Lh, i.e. when we rotate (using the center of
86
// the coordinate system as the center of rotation) 'point' and Lh in such a way that Lh points
87
// directly upwards, is 'point' on the left or the right of it?
88

    
89
  private boolean isOnTheLeft(float[] point, float distance, float angle)
90
    {
91
    float sin = (float)Math.sin(angle);
92
    float cos = (float)Math.cos(angle);
93

    
94
    float vx = point[0] + sin*distance;
95
    float vy = point[1] - cos*distance;
96

    
97
    return vx*sin < vy*cos;
98
    }
99

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

    
102
  int returnPart(int type, int face, float[] point)
103
    {
104
    switch(type)
105
      {
106
      case TYPE_NOT_SPLIT      : return 0;
107
      case TYPE_SPLIT_EDGE     : return partEdge(point,face);
108
      case TYPE_SPLIT_EDGE_COIN: float y = point[1];
109
                                 float x = point[0];
110
                                 float dist = D_PENTA*DIST2D;
111
                                 return partEdge(point,face) + (x*x+y*y < dist*dist ? 0:5 );
112
      case TYPE_SPLIT_CORNER   : // not supported
113
      }
114

    
115
    return 0;
116
    }
117

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

    
126
  private int partEdge(float[] point, int face)
127
    {
128
    float angle = returnAngle(face);
129
    float A = (float)(Math.PI/5);
130

    
131
    for(int i=0; i<5; i++)
132
      {
133
      if( isOnTheLeft(point, DIST2D, (9-2*i)*A-angle) ) return -1;
134
      }
135

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

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  boolean isInsideFace(int face, float[] p)
160
    {
161
    float angle = returnAngle(face);
162
    float A = (float)(Math.PI/5);
163

    
164
    for(int i=0; i<5; i++)
165
      {
166
      if( isOnTheLeft(p, DIST2D, (9-2*i)*A-angle) ) return false;
167
      }
168

    
169
    return true;
170
    }
171
}
(4-4/13)