~ubuntu-branches/ubuntu/precise/graphviz/precise-security

« back to all changes in this revision

Viewing changes to cmd/smyrna/trackball.c

  • Committer: Bazaar Package Importer
  • Author(s): David Claughton
  • Date: 2010-03-24 22:45:18 UTC
  • mfrom: (1.2.7 upstream) (6.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100324224518-do441tthbqjaqjzd
Tags: 2.26.3-4
Add patch to fix segfault in circo. Backported from upstream snapshot
release.  Thanks to Francis Russell for his work on this.
(Closes: #575255)

Show diffs side-by-side

added added

removed removed

Lines of Context:
65
65
 * Local function prototypes (not defined in trackball.h)
66
66
 */
67
67
static float tb_project_to_sphere(float, float, float);
68
 
static void normalize_quat(float [4]);
 
68
static void normalize_quat(float[4]);
69
69
 
70
 
void
71
 
vzero(float *v)
 
70
void vzero(float *v)
72
71
{
73
72
    v[0] = 0.0;
74
73
    v[1] = 0.0;
75
74
    v[2] = 0.0;
76
75
}
77
76
 
78
 
void
79
 
vset(float *v, float x, float y, float z)
 
77
void vset(float *v, float x, float y, float z)
80
78
{
81
79
    v[0] = x;
82
80
    v[1] = y;
83
81
    v[2] = z;
84
82
}
85
83
 
86
 
void
87
 
vsub(const float *src1, const float *src2, float *dst)
 
84
void vsub(const float *src1, const float *src2, float *dst)
88
85
{
89
86
    dst[0] = src1[0] - src2[0];
90
87
    dst[1] = src1[1] - src2[1];
91
88
    dst[2] = src1[2] - src2[2];
92
89
}
93
90
 
94
 
void
95
 
vcopy(const float *v1, float *v2)
 
91
void vcopy(const float *v1, float *v2)
96
92
{
97
93
    register int i;
98
 
    for (i = 0 ; i < 3 ; i++)
99
 
        v2[i] = v1[i];
 
94
    for (i = 0; i < 3; i++)
 
95
        v2[i] = v1[i];
100
96
}
101
97
 
102
 
void
103
 
vcross(const float *v1, const float *v2, float *cross)
 
98
void vcross(const float *v1, const float *v2, float *cross)
104
99
{
105
100
    float temp[3];
106
101
 
110
105
    vcopy(temp, cross);
111
106
}
112
107
 
113
 
float
114
 
vlength(const float *v)
 
108
float vlength(const float *v)
115
109
{
116
110
    return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
117
111
}
118
112
 
119
 
void
120
 
vscale(float *v, float div)
 
113
void vscale(float *v, float div)
121
114
{
122
115
    v[0] *= div;
123
116
    v[1] *= div;
124
117
    v[2] *= div;
125
118
}
126
119
 
127
 
void
128
 
vnormal(float *v)
129
 
{
130
 
    vscale(v,1.0/vlength(v));
131
 
}
132
 
 
133
 
float
134
 
vdot(const float *v1, const float *v2)
135
 
{
136
 
    return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
137
 
}
138
 
 
139
 
void
140
 
vadd(const float *src1, const float *src2, float *dst)
 
120
void vnormal(float *v)
 
121
{
 
122
    vscale(v, 1.0 / vlength(v));
 
123
}
 
124
 
 
125
float vdot(const float *v1, const float *v2)
 
126
{
 
127
    return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
 
128
}
 
129
 
 
130
void vadd(const float *src1, const float *src2, float *dst)
141
131
{
142
132
    dst[0] = src1[0] + src2[0];
143
133
    dst[1] = src1[1] + src2[1];
156
146
 * It is assumed that the arguments to this routine are in the range
157
147
 * (-1.0 ... 1.0)
158
148
 */
159
 
void
160
 
trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
 
149
void trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
161
150
{
162
 
    float a[3]; /* Axis of rotation */
163
 
    float phi;  /* how much to rotate about axis */
 
151
    float a[3];                 /* Axis of rotation */
 
152
    float phi;                  /* how much to rotate about axis */
164
153
    float p1[3], p2[3], d[3];
165
154
    float t;
166
155
 
167
156
    if (p1x == p2x && p1y == p2y) {
168
 
        /* Zero rotation */
169
 
        vzero(q);
170
 
        q[3] = 1.0;
171
 
        return;
 
157
        /* Zero rotation */
 
158
        vzero(q);
 
159
        q[3] = 1.0;
 
160
        return;
172
161
    }
173
162
 
174
163
    /*
175
164
     * First, figure out z-coordinates for projection of P1 and P2 to
176
165
     * deformed sphere
177
166
     */
178
 
    vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));
179
 
    vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y));
 
167
    vset(p1, p1x, p1y, tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y));
 
168
    vset(p2, p2x, p2y, tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y));
180
169
 
181
170
    /*
182
171
     *  Now, we want the cross product of P1 and P2
183
172
     */
184
 
    vcross(p2,p1,a);
 
173
    vcross(p2, p1, a);
185
174
 
186
175
    /*
187
176
     *  Figure out how much to rotate around that axis.
188
177
     */
189
 
    vsub(p1,p2,d);
190
 
    t = vlength(d) / (2.0*TRACKBALLSIZE);
 
178
    vsub(p1, p2, d);
 
179
    t = vlength(d) / (2.0 * TRACKBALLSIZE);
191
180
 
192
181
    /*
193
182
     * Avoid problems with out-of-control values...
194
183
     */
195
 
    if (t > 1.0) t = 1.0;
196
 
    if (t < -1.0) t = -1.0;
 
184
    if (t > 1.0)
 
185
        t = 1.0;
 
186
    if (t < -1.0)
 
187
        t = -1.0;
197
188
    phi = 2.0 * asin(t);
198
189
 
199
 
    axis_to_quat(a,phi,q);
 
190
    axis_to_quat(a, phi, q);
200
191
}
201
192
 
202
193
/*
203
194
 *  Given an axis and angle, compute quaternion.
204
195
 */
205
 
void
206
 
axis_to_quat(float a[3], float phi, float q[4])
 
196
void axis_to_quat(float a[3], float phi, float q[4])
207
197
{
208
198
    vnormal(a);
209
 
    vcopy(a,q);
210
 
    vscale(q,sin(phi/2.0));
211
 
    q[3] = cos(phi/2.0);
 
199
    vcopy(a, q);
 
200
    vscale(q, sin(phi / 2.0));
 
201
    q[3] = cos(phi / 2.0);
212
202
}
213
203
 
214
204
/*
215
205
 * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
216
206
 * if we are away from the center of the sphere.
217
207
 */
218
 
static float
219
 
tb_project_to_sphere(float r, float x, float y)
 
208
static float tb_project_to_sphere(float r, float x, float y)
220
209
{
221
210
    float d, t, z;
222
211
 
223
 
    d = sqrt(x*x + y*y);
224
 
    if (d < r * 0.70710678118654752440) {    /* Inside sphere */
225
 
        z = sqrt(r*r - d*d);
226
 
    } else {           /* On hyperbola */
227
 
        t = r / 1.41421356237309504880;
228
 
        z = t*t / d;
 
212
    d = sqrt(x * x + y * y);
 
213
    if (d < r * 0.70710678118654752440) {       /* Inside sphere */
 
214
        z = sqrt(r * r - d * d);
 
215
    } else {                    /* On hyperbola */
 
216
        t = r / 1.41421356237309504880;
 
217
        z = t * t / d;
229
218
    }
230
219
    return z;
231
220
}
243
232
 
244
233
#define RENORMCOUNT 97
245
234
 
246
 
void
247
 
add_quats(float q1[4], float q2[4], float dest[4])
 
235
void add_quats(float q1[4], float q2[4], float dest[4])
248
236
{
249
 
    static int count=0;
 
237
    static int count = 0;
250
238
    float t1[4], t2[4], t3[4];
251
239
    float tf[4];
252
240
 
253
 
    vcopy(q1,t1);
254
 
    vscale(t1,q2[3]);
255
 
 
256
 
    vcopy(q2,t2);
257
 
    vscale(t2,q1[3]);
258
 
 
259
 
    vcross(q2,q1,t3);
260
 
    vadd(t1,t2,tf);
261
 
    vadd(t3,tf,tf);
262
 
    tf[3] = q1[3] * q2[3] - vdot(q1,q2);
 
241
    vcopy(q1, t1);
 
242
    vscale(t1, q2[3]);
 
243
 
 
244
    vcopy(q2, t2);
 
245
    vscale(t2, q1[3]);
 
246
 
 
247
    vcross(q2, q1, t3);
 
248
    vadd(t1, t2, tf);
 
249
    vadd(t3, tf, tf);
 
250
    tf[3] = q1[3] * q2[3] - vdot(q1, q2);
263
251
 
264
252
    dest[0] = tf[0];
265
253
    dest[1] = tf[1];
267
255
    dest[3] = tf[3];
268
256
 
269
257
    if (++count > RENORMCOUNT) {
270
 
        count = 0;
271
 
        normalize_quat(dest);
 
258
        count = 0;
 
259
        normalize_quat(dest);
272
260
    }
273
261
}
274
262
 
284
272
 * - Pletinckx, D., Quaternion calculus as a basic tool in computer
285
273
 *   graphics, The Visual Computer 5, 2-13, 1989.
286
274
 */
287
 
static void
288
 
normalize_quat(float q[4])
 
275
static void normalize_quat(float q[4])
289
276
{
290
277
    int i;
291
278
    float mag;
292
279
 
293
 
    mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
294
 
    for (i = 0; i < 4; i++) q[i] /= mag;
 
280
    mag = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
 
281
    for (i = 0; i < 4; i++)
 
282
        q[i] /= mag;
295
283
}
296
284
 
297
285
/*
298
286
 * Build a rotation matrix, given a quaternion rotation.
299
287
 *
300
288
 */
301
 
void
302
 
build_rotmatrix(float m[4][4], float q[4])
 
289
void build_rotmatrix(float m[4][4], float q[4])
303
290
{
304
291
    m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
305
292
    m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
307
294
    m[0][3] = 0.0;
308
295
 
309
296
    m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
310
 
    m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
 
297
    m[1][1] = 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
311
298
    m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
312
299
    m[1][3] = 0.0;
313
300
 
321
308
    m[3][2] = 0.0;
322
309
    m[3][3] = 1.0;
323
310
}
324