Project

General

Profile

« Previous | Next » 

Revision 7aa4c349

Added by Leszek Koltunski almost 3 years ago

Progress with RubikControl.

View differences:

src/main/java/org/distorted/helpers/QuatHelper.java
28 28
///////////////////////////////////////////////////////////////////////////////////////////////////
29 29
// return quat1*quat2
30 30

  
31
    public static Static4D quatMultiply( Static4D quat1, Static4D quat2 )
32
      {
33
      float qx = quat1.get0();
34
      float qy = quat1.get1();
35
      float qz = quat1.get2();
36
      float qw = quat1.get3();
37

  
38
      float rx = quat2.get0();
39
      float ry = quat2.get1();
40
      float rz = quat2.get2();
41
      float rw = quat2.get3();
42

  
43
      float tx = rw*qx - rz*qy + ry*qz + rx*qw;
44
      float ty = rw*qy + rz*qx + ry*qw - rx*qz;
45
      float tz = rw*qz + rz*qw - ry*qx + rx*qy;
46
      float tw = rw*qw - rz*qz - ry*qy - rx*qx;
47

  
48
      return new Static4D(tx,ty,tz,tw);
49
      }
31
  public static Static4D quatMultiply( Static4D quat1, Static4D quat2 )
32
    {
33
    float qx = quat1.get0();
34
    float qy = quat1.get1();
35
    float qz = quat1.get2();
36
    float qw = quat1.get3();
37

  
38
    float rx = quat2.get0();
39
    float ry = quat2.get1();
40
    float rz = quat2.get2();
41
    float rw = quat2.get3();
42

  
43
    float tx = rw*qx - rz*qy + ry*qz + rx*qw;
44
    float ty = rw*qy + rz*qx + ry*qw - rx*qz;
45
    float tz = rw*qz + rz*qw - ry*qx + rx*qy;
46
    float tw = rw*qw - rz*qz - ry*qy - rx*qx;
47

  
48
    return new Static4D(tx,ty,tz,tw);
49
    }
50 50

  
51 51
///////////////////////////////////////////////////////////////////////////////////////////////////
52 52
// rotate 'vector' by quat  ( i.e. return quat*vector*(quat^-1) )
53 53

  
54
    public static Static4D rotateVectorByQuat(Static4D vector, Static4D quat)
55
      {
56
      float qx = quat.get0();
57
      float qy = quat.get1();
58
      float qz = quat.get2();
59
      float qw = quat.get3();
54
  public static Static4D rotateVectorByQuat(Static4D vector, Static4D quat)
55
    {
56
    float qx = quat.get0();
57
    float qy = quat.get1();
58
    float qz = quat.get2();
59
    float qw = quat.get3();
60 60

  
61
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
62
      Static4D tmp = quatMultiply(quat,vector);
61
    Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
62
    Static4D tmp = quatMultiply(quat,vector);
63 63

  
64
      return quatMultiply(tmp,quatInverted);
65
      }
64
    return quatMultiply(tmp,quatInverted);
65
    }
66 66

  
67 67
///////////////////////////////////////////////////////////////////////////////////////////////////
68 68
// rotate 'vector' by quat^(-1)  ( i.e. return (quat^-1)*vector*quat )
69 69

  
70
    public static Static4D rotateVectorByInvertedQuat(Static4D vector, Static4D quat)
70
  public static Static4D rotateVectorByInvertedQuat(Static4D vector, Static4D quat)
71
    {
72
    float qx = quat.get0();
73
    float qy = quat.get1();
74
    float qz = quat.get2();
75
    float qw = quat.get3();
76

  
77
    Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
78
    Static4D tmp = quatMultiply(quatInverted,vector);
79

  
80
    return quatMultiply(tmp,quat);
81
    }
82

  
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

  
85
  public static Static4D quatFromDrag(float dragX, float dragY)
86
    {
87
    float axisX = dragY;  // inverted X and Y - rotation axis is perpendicular to (dragX,dragY)
88
    float axisY = dragX;  // Why not (-dragY, dragX) ? because Y axis is also inverted!
89
    float axisZ = 0;
90
    float axisL = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
91

  
92
    if( axisL>0 )
71 93
      {
72
      float qx = quat.get0();
73
      float qy = quat.get1();
74
      float qz = quat.get2();
75
      float qw = quat.get3();
94
      axisX /= axisL;
95
      axisY /= axisL;
96
      axisZ /= axisL;
97

  
98
      float ratio = axisL;
99
      ratio = ratio - (int)ratio;     // the cos() is only valid in (0,Pi)
76 100

  
77
      Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
78
      Static4D tmp = quatMultiply(quatInverted,vector);
101
      float cosA = (float)Math.cos(Math.PI*ratio);
102
      float sinA = (float)Math.sqrt(1-cosA*cosA);
79 103

  
80
      return quatMultiply(tmp,quat);
104
      return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
81 105
      }
82 106

  
107
    return new Static4D(0f, 0f, 0f, 1f);
108
    }
109

  
83 110
///////////////////////////////////////////////////////////////////////////////////////////////////
84 111

  
85
    public static Static4D quatFromDrag(float dragX, float dragY)
86
      {
87
      float axisX = dragY;  // inverted X and Y - rotation axis is perpendicular to (dragX,dragY)
88
      float axisY = dragX;  // Why not (-dragY, dragX) ? because Y axis is also inverted!
89
      float axisZ = 0;
90
      float axisL = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
112
  public static double computeCos(double oldX, double oldY, double newX, double newY, double len1, double len2)
113
    {
114
    double ret= (oldX*newX+oldY*newY) / (len1*len2);
115
    if( ret<-1.0 ) return -1.0;
116
    if( ret> 1.0 ) return  1.0;
117

  
118
    return ret;
119
    }
120

  
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122
// sin of (signed!) angle between vectors 'old' and 'new', counterclockwise!
91 123

  
92
      if( axisL>0 )
93
        {
94
        axisX /= axisL;
95
        axisY /= axisL;
96
        axisZ /= axisL;
124
  public static double computeSin(double oldX, double oldY, double newX, double newY, double len1, double len2)
125
    {
126
    double ret= (newX*oldY-oldX*newY) / (len1*len2);
127
    if( ret<-1.0 ) return -1.0;
128
    if( ret> 1.0 ) return  1.0;
97 129

  
98
        float ratio = axisL;
99
        ratio = ratio - (int)ratio;     // the cos() is only valid in (0,Pi)
130
    return ret;
131
    }
100 132

  
101
        float cosA = (float)Math.cos(Math.PI*ratio);
102
        float sinA = (float)Math.sqrt(1-cosA*cosA);
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134
// return quat Q that turns 3D vector A=(ax,ay,az) to another 3D vector B=(bx,by,bz)
135
// take care of double-cover by ensuring that always Q.get3() >=0
136

  
137
  public static Static4D retRotationQuat(float ax, float ay, float az, float bx, float by, float bz)
138
    {
139
    float nx = ay*bz - az*by;
140
    float ny = az*bx - ax*bz;
141
    float nz = ax*by - ay*bx;
103 142

  
104
        return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
105
        }
143
    float sin = (float)Math.sqrt(nx*nx + ny*ny + nz*nz);
144
    float cos = ax*bx + ay*by + az*bz;
106 145

  
107
      return new Static4D(0f, 0f, 0f, 1f);
146
    if( sin!=0 )
147
      {
148
      nx /= sin;
149
      ny /= sin;
150
      nz /= sin;
108 151
      }
152

  
153
    // Why sin<=0 and cos>=0 ?
154
    // 0<angle<180 -> 0<halfAngle<90 -> both sin and cos are positive.
155
    // But1: quats work counterclockwise -> negate cos.
156
    // But2: double-cover, we prefer to have the cos positive (so that unit=(0,0,0,1))
157
    // so negate again both cos and sin.
158
    float sinHalf =-(float)Math.sqrt((1-cos)/2);
159
    float cosHalf = (float)Math.sqrt((1+cos)/2);
160

  
161
    return new Static4D(nx*sinHalf,ny*sinHalf,nz*sinHalf,cosHalf);
162
    }
109 163
  }

Also available in: Unified diff