~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to extern/eltopo/common/tunicate/intersection.cpp

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Released into the public domain by Robert Bridson, 2009.
2
 
 
3
 
#include <cassert>
4
 
#include <cmath>
5
 
#include <iostream>
6
 
#include <tunicate.h>
7
 
 
8
 
//==============================================================================
9
 
static bool
10
 
same_sign(double a, double b)
11
 
{
12
 
    return (a<=0 && b<=0) || (a>=0 && b>=0);
13
 
}
14
 
 
15
 
//==============================================================================
16
 
int
17
 
simplex_intersection1d(int k,
18
 
                       const double* x0,
19
 
                       const double* x1,
20
 
                       const double* x2,
21
 
                       double* alpha0, 
22
 
                       double* alpha1, 
23
 
                       double* alpha2)
24
 
{
25
 
    assert(1<=k && k<=2);
26
 
    assert(alpha0 && alpha1 && alpha2);
27
 
    if(k==1){
28
 
        if(x1[0]<x2[0]){
29
 
            if(x0[0]<x1[0]) return 0;
30
 
            else if(x0[0]>x2[0]) return 0;
31
 
            *alpha0=1;
32
 
            *alpha1=(x2[0]-x0[0])/(x2[0]-x1[0]);
33
 
            *alpha2=(x0[0]-x1[0])/(x2[0]-x1[0]);
34
 
            return 1;
35
 
        }else if(x1[0]>x2[0]){
36
 
            if(x0[0]<x2[0]) return 0;
37
 
            else if(x0[0]>x1[0]) return 0;
38
 
            *alpha0=1;
39
 
            *alpha1=(x2[0]-x0[0])/(x2[0]-x1[0]);
40
 
            *alpha2=(x0[0]-x1[0])/(x2[0]-x1[0]);
41
 
            return 1;
42
 
        }else{ // x1[0]==x2[0]
43
 
            if(x0[0]!=x1[0]) return 0;
44
 
            *alpha0=1;
45
 
            *alpha1=0.5;
46
 
            *alpha2=0.5;
47
 
            return 1;
48
 
        }
49
 
    }else
50
 
        return simplex_intersection1d(1, x2, x1, 0, alpha2, alpha1, alpha0);
51
 
}
52
 
 
53
 
//==============================================================================
54
 
// degenerate test in 2d - assumes three points lie on the same line
55
 
static int
56
 
simplex_intersection2d(int k,
57
 
                       const double* x0,
58
 
                       const double* x1,
59
 
                       const double* x2,
60
 
                       double* alpha0, 
61
 
                       double* alpha1, 
62
 
                       double* alpha2)
63
 
{
64
 
    assert(k==1);
65
 
    // try projecting each coordinate out in turn
66
 
    double ax0, ax1, ax2;
67
 
    if(!simplex_intersection1d(1, x0+1, x1+1, x2+1, &ax0, &ax1, &ax2)) return 0;
68
 
    double ay0, ay1, ay2;
69
 
    if(!simplex_intersection1d(1, x0, x1, x2, &ay0, &ay1, &ay2)) return 0;
70
 
    // decide which solution is more accurate for barycentric coordinates
71
 
    double checkx=std::fabs(-ax0*x0[0]+ax1*x1[0]+ax2*x2[0])
72
 
    +std::fabs(-ax0*x0[1]+ax1*x1[1]+ax2*x2[1]);
73
 
    double checky=std::fabs(-ay0*x0[0]+ay1*x1[0]+ay2*x2[0])
74
 
    +std::fabs(-ay0*x0[1]+ay1*x1[1]+ay2*x2[1]);
75
 
    if(checkx<=checky){
76
 
        *alpha0=ax0;
77
 
        *alpha1=ax1;
78
 
        *alpha2=ax2;
79
 
    }else{
80
 
        *alpha0=ay0;
81
 
        *alpha1=ay1;
82
 
        *alpha2=ay2;
83
 
    }
84
 
    return 1;
85
 
}
86
 
 
87
 
//==============================================================================
88
 
int
89
 
simplex_intersection2d(int k,
90
 
                       const double* x0,
91
 
                       const double* x1,
92
 
                       const double* x2,
93
 
                       const double* x3,
94
 
                       double* alpha0, 
95
 
                       double* alpha1, 
96
 
                       double* alpha2,
97
 
                       double* alpha3)
98
 
{
99
 
    assert(1<=k && k<=3);
100
 
    double sum1, sum2;
101
 
    switch(k){
102
 
        case 1: // point vs. triangle
103
 
            *alpha1=-orientation2d(x0, x2, x3);
104
 
            *alpha2= orientation2d(x0, x1, x3);
105
 
            if(!same_sign(*alpha1, *alpha2)) return 0;
106
 
            *alpha3=-orientation2d(x0, x1, x2);
107
 
            if(!same_sign(*alpha1, *alpha3)) return 0;
108
 
            if(!same_sign(*alpha2, *alpha3)) return 0;
109
 
            sum2=*alpha1+*alpha2+*alpha3;
110
 
            if(sum2){ // triangle not degenerate?
111
 
                *alpha0=1;
112
 
                *alpha1/=sum2;
113
 
                *alpha2/=sum2;
114
 
                *alpha3/=sum2;
115
 
                return 1;
116
 
            }else{ // triangle is degenerate and point lies on same line
117
 
                if(simplex_intersection2d(1, x0, x1, x2, alpha0, alpha1, alpha2)){
118
 
                    *alpha3=0;
119
 
                    return 1;
120
 
                }
121
 
                if(simplex_intersection2d(1, x0, x1, x3, alpha0, alpha1, alpha3)){
122
 
                    *alpha2=0;
123
 
                    return 1;
124
 
                }
125
 
                if(simplex_intersection2d(1, x0, x2, x3, alpha0, alpha2, alpha3)){
126
 
                    *alpha1=0;
127
 
                    return 1;
128
 
                }
129
 
                return 0;
130
 
            }
131
 
            
132
 
        case 2: // segment vs. segment
133
 
            *alpha0= orientation2d(x1, x2, x3);
134
 
            *alpha1=-orientation2d(x0, x2, x3);
135
 
            if(!same_sign(*alpha0, *alpha1)) return 0;
136
 
            *alpha2= orientation2d(x0, x1, x3);
137
 
            *alpha3=-orientation2d(x0, x1, x2);
138
 
            if(!same_sign(*alpha2, *alpha3)) return 0;
139
 
            sum1=*alpha0+*alpha1;
140
 
            sum2=*alpha2+*alpha3;
141
 
            if(sum1 && sum2){
142
 
                *alpha0/=sum1;
143
 
                *alpha1/=sum1;
144
 
                *alpha2/=sum2;
145
 
                *alpha3/=sum2;
146
 
                return 1;
147
 
            }else{ // degenerate: segments lie on the same line
148
 
                if(simplex_intersection2d(1, x0, x2, x3, alpha0, alpha2, alpha3)){
149
 
                    *alpha1=0;
150
 
                    return 1;
151
 
                }
152
 
                if(simplex_intersection2d(1, x1, x2, x3, alpha1, alpha2, alpha3)){
153
 
                    *alpha0=0;
154
 
                    return 1;
155
 
                }
156
 
                if(simplex_intersection2d(1, x2, x0, x1, alpha2, alpha0, alpha1)){
157
 
                    *alpha3=0;
158
 
                    return 1;
159
 
                }
160
 
                if(simplex_intersection2d(1, x3, x0, x1, alpha3, alpha0, alpha1)){
161
 
                    *alpha2=0;
162
 
                    return 1;
163
 
                }
164
 
                return 0;
165
 
            }
166
 
        case 3: // triangle vs. point
167
 
            return simplex_intersection2d(1, x3, x2, x1, x0,
168
 
                                          alpha3, alpha2, alpha1, alpha0);
169
 
        default:
170
 
            return -1; // should never get here
171
 
    }
172
 
}
173
 
 
174
 
//==============================================================================
175
 
// degenerate test in 3d - assumes four points lie on the same plane
176
 
static int
177
 
simplex_intersection3d(int k,
178
 
                       const double* x0,
179
 
                       const double* x1,
180
 
                       const double* x2,
181
 
                       const double* x3,
182
 
                       double* alpha0, 
183
 
                       double* alpha1, 
184
 
                       double* alpha2,
185
 
                       double* )
186
 
{
187
 
    assert(k<=2);
188
 
    // try projecting each coordinate out in turn
189
 
    double ax0, ax1, ax2, ax3;
190
 
    if(!simplex_intersection2d(k, x0+1, x1+1, x2+1, x3+1, &ax0, &ax1, &ax2,&ax3))
191
 
        return 0;
192
 
    double ay0, ay1, ay2, ay3;
193
 
    double p0[2]={x0[0], x0[2]}, p1[2]={x1[0], x1[2]},
194
 
    p2[2]={x2[0], x2[2]}, p3[2]={x3[0], x3[2]};
195
 
    if(!simplex_intersection2d(k, p0, p1, p2, p3, &ay0, &ay1, &ay2, &ay3))
196
 
        return 0;
197
 
    double az0, az1, az2, az3;
198
 
    if(!simplex_intersection2d(k, x0, x1, x2, x3, &az0, &az1, &az2, &az3))
199
 
        return 0;
200
 
    // decide which solution is more accurate for barycentric coordinates
201
 
    double checkx, checky, checkz;
202
 
    if(k==1){
203
 
        checkx=std::fabs(-ax0*x0[0]+ax1*x1[0]+ax2*x2[0]+ax3*x3[0])
204
 
        +std::fabs(-ax0*x0[1]+ax1*x1[1]+ax2*x2[1]+ax3*x3[1])
205
 
        +std::fabs(-ax0*x0[2]+ax1*x1[2]+ax2*x2[2]+ax3*x3[2]);
206
 
        checky=std::fabs(-ay0*x0[0]+ay1*x1[0]+ay2*x2[0]+ay3*x3[0])
207
 
        +std::fabs(-ay0*x0[1]+ay1*x1[1]+ay2*x2[1]+ay3*x3[1])
208
 
        +std::fabs(-ay0*x0[2]+ay1*x1[2]+ay2*x2[2]+ay3*x3[2]);
209
 
        checkz=std::fabs(-az0*x0[0]+az1*x1[0]+az2*x2[0]+az3*x3[0])
210
 
        +std::fabs(-az0*x0[1]+az1*x1[1]+az2*x2[1]+az3*x3[1])
211
 
        +std::fabs(-az0*x0[2]+az1*x1[2]+az2*x2[2]+az3*x3[2]);
212
 
    }else{
213
 
        checkx=std::fabs(-ax0*x0[0]-ax1*x1[0]+ax2*x2[0]+ax3*x3[0])
214
 
        +std::fabs(-ax0*x0[1]-ax1*x1[1]+ax2*x2[1]+ax3*x3[1])
215
 
        +std::fabs(-ax0*x0[2]-ax1*x1[2]+ax2*x2[2]+ax3*x3[2]);
216
 
        checky=std::fabs(-ay0*x0[0]-ay1*x1[0]+ay2*x2[0]+ay3*x3[0])
217
 
        +std::fabs(-ay0*x0[1]-ay1*x1[1]+ay2*x2[1]+ay3*x3[1])
218
 
        +std::fabs(-ay0*x0[2]-ay1*x1[2]+ay2*x2[2]+ay3*x3[2]);
219
 
        checkz=std::fabs(-az0*x0[0]-az1*x1[0]+az2*x2[0]+az3*x3[0])
220
 
        +std::fabs(-az0*x0[1]-az1*x1[1]+az2*x2[1]+az3*x3[1])
221
 
        +std::fabs(-az0*x0[2]-az1*x1[2]+az2*x2[2]+az3*x3[2]);
222
 
    }
223
 
    if(checkx<=checky && checkx<=checkz){
224
 
        *alpha0=ax0;
225
 
        *alpha1=ax1;
226
 
        *alpha2=ax2;
227
 
        *alpha2=ax3;
228
 
    }else if(checky<=checkz){
229
 
        *alpha0=ay0;
230
 
        *alpha1=ay1;
231
 
        *alpha2=ay2;
232
 
        *alpha2=ay3;
233
 
    }else{
234
 
        *alpha0=az0;
235
 
        *alpha1=az1;
236
 
        *alpha2=az2;
237
 
        *alpha2=az3;
238
 
    }
239
 
    return 1;
240
 
}
241
 
 
242
 
//==============================================================================
243
 
int
244
 
simplex_intersection3d(int k,
245
 
                       const double* x0,
246
 
                       const double* x1,
247
 
                       const double* x2,
248
 
                       const double* x3,
249
 
                       const double* x4,
250
 
                       double* alpha0, 
251
 
                       double* alpha1, 
252
 
                       double* alpha2,
253
 
                       double* alpha3,
254
 
                       double* alpha4)
255
 
{
256
 
    assert(1<=k && k<=4);
257
 
    double sum1, sum2;
258
 
    switch(k){
259
 
        case 1: // point vs. tetrahedron
260
 
            *alpha1=-orientation3d(x0, x2, x3, x4);
261
 
            *alpha2= orientation3d(x0, x1, x3, x4);
262
 
            if(!same_sign(*alpha1, *alpha2)) return 0;
263
 
            *alpha3=-orientation3d(x0, x1, x2, x4);
264
 
            if(!same_sign(*alpha1, *alpha3)) return 0;
265
 
            if(!same_sign(*alpha2, *alpha3)) return 0;
266
 
            *alpha4= orientation3d(x0, x1, x2, x3);
267
 
            if(!same_sign(*alpha1, *alpha4)) return 0;
268
 
            if(!same_sign(*alpha2, *alpha4)) return 0;         
269
 
            if(!same_sign(*alpha3, *alpha4)) return 0;                  
270
 
            *alpha0=1;
271
 
            sum2=*alpha1+*alpha2+*alpha3+*alpha4;
272
 
            if(sum2){
273
 
                *alpha1/=sum2;
274
 
                *alpha2/=sum2;
275
 
                *alpha3/=sum2;
276
 
                *alpha4/=sum2;
277
 
                return 1;
278
 
            }else{ // degenerate: point and tetrahedron in same plane
279
 
                if(simplex_intersection3d(1, x0, x2, x3, x4,
280
 
                                          alpha0, alpha2, alpha3, alpha4)){
281
 
                    *alpha1=0;
282
 
                    return 1;
283
 
                }
284
 
                if(simplex_intersection3d(1, x0, x1, x3, x4,
285
 
                                          alpha0, alpha1, alpha3, alpha4)){
286
 
                    *alpha2=0;
287
 
                    return 1;
288
 
                }
289
 
                if(simplex_intersection3d(1, x0, x1, x2, x4,
290
 
                                          alpha0, alpha1, alpha2, alpha4)){
291
 
                    *alpha3=0;
292
 
                    return 1;
293
 
                }
294
 
                if(simplex_intersection3d(1, x0, x1, x2, x3,
295
 
                                          alpha0, alpha1, alpha2, alpha3)){
296
 
                    *alpha4=0;
297
 
                    return 1;
298
 
                }
299
 
                return 0;
300
 
            }
301
 
            
302
 
        case 2: // segment vs. triangle
303
 
            *alpha0= orientation3d(x1, x2, x3, x4);
304
 
            *alpha1=-orientation3d(x0, x2, x3, x4);
305
 
            if(!same_sign(*alpha0, *alpha1)) return 0;
306
 
            *alpha2= orientation3d(x0, x1, x3, x4);
307
 
            *alpha3=-orientation3d(x0, x1, x2, x4);
308
 
            if(!same_sign(*alpha2, *alpha3)) return 0;
309
 
            *alpha4= orientation3d(x0, x1, x2, x3);
310
 
            if(!same_sign(*alpha2, *alpha4)) return 0;
311
 
            if(!same_sign(*alpha3, *alpha4)) return 0;
312
 
            sum1=*alpha0+*alpha1;
313
 
            sum2=*alpha2+*alpha3+*alpha4;
314
 
            
315
 
            if(sum1 && sum2){
316
 
                *alpha0/=sum1;
317
 
                *alpha1/=sum1;
318
 
                *alpha2/=sum2;
319
 
                *alpha3/=sum2;
320
 
                *alpha4/=sum2;
321
 
                return 1;
322
 
            }else{ // degenerate: segment and triangle in same plane
323
 
                if(simplex_intersection3d(1, x1, x2, x3, x4,
324
 
                                          alpha1, alpha2, alpha3, alpha4)){
325
 
                    *alpha0=0;
326
 
                    return 1;
327
 
                }
328
 
                if(simplex_intersection3d(1, x0, x2, x3, x4,
329
 
                                          alpha0, alpha2, alpha3, alpha4)){
330
 
                    *alpha1=0;
331
 
                    return 1;
332
 
                }
333
 
                if(simplex_intersection3d(2, x0, x1, x3, x4,
334
 
                                          alpha0, alpha1, alpha3, alpha4)){
335
 
                    *alpha2=0;
336
 
                    return 1;
337
 
                }
338
 
                if(simplex_intersection3d(2, x0, x1, x2, x4,
339
 
                                          alpha0, alpha1, alpha2, alpha4)){
340
 
                    *alpha3=0;
341
 
                    return 1;
342
 
                }
343
 
                if(simplex_intersection3d(2, x0, x1, x2, x3,
344
 
                                          alpha0, alpha1, alpha2, alpha3)){
345
 
                    *alpha4=0;
346
 
                    return 1;
347
 
                }
348
 
                return 0;
349
 
            }
350
 
            
351
 
        case 3: // triangle vs. segment
352
 
        case 4: // tetrahedron vs. point
353
 
            return simplex_intersection3d(5-k, x4, x3, x2, x1, x0,
354
 
                                          alpha4, alpha3, alpha2, alpha1, alpha0);
355
 
        default:
356
 
            return -1; // should never get here
357
 
    }
358
 
}
359
 
 
360
 
//==============================================================================
361
 
// degenerate test in 3d+time - assumes five points lie on the same hyper-plane
362
 
static int
363
 
simplex_intersection_time3d(int k,
364
 
                            const double* x0, int time0,
365
 
                            const double* x1, int time1,
366
 
                            const double* x2, int time2,
367
 
                            const double* x3, int time3,
368
 
                            const double* x4, int time4,
369
 
                            double* alpha0, 
370
 
                            double* alpha1, 
371
 
                            double* alpha2,
372
 
                            double* alpha3,
373
 
                            double* )
374
 
{
375
 
    assert(k<=2);
376
 
    assert(time0==0 || time0==1);
377
 
    assert(time1==0 || time1==1);
378
 
    assert(time2==0 || time2==1);
379
 
    assert(time3==0 || time3==1);
380
 
    assert(time4==0 || time4==1);
381
 
    // try projecting each coordinate out in turn
382
 
    double ax0, ax1, ax2, ax3, ax4;
383
 
    double r0[3]={x0[0], x0[2], time0}, r1[3]={x1[0], x1[2], time1},
384
 
    r2[3]={x2[0], x2[2], time2}, r3[3]={x3[0], x3[2], time3},
385
 
    r4[3]={x4[0], x4[2], time4};
386
 
    if(!simplex_intersection3d(k, r0, r1, r2, r3, r4,
387
 
                               &ax0, &ax1, &ax2, &ax3, &ax4)) return 0;
388
 
    double ay0, ay1, ay2, ay3, ay4;
389
 
    double p0[3]={x0[0], x0[2], time0}, p1[3]={x1[0], x1[2], time1},
390
 
    p2[3]={x2[0], x2[2], time2}, p3[3]={x3[0], x3[2], time3},
391
 
    p4[3]={x4[0], x4[2], time4};
392
 
    if(!simplex_intersection3d(k, p0, p1, p2, p3, p4,
393
 
                               &ay0, &ay1, &ay2, &ay3, &ay4)) return 0;
394
 
    double az0, az1, az2, az3, az4;
395
 
    double q0[3]={x0[0], x0[1], time0}, q1[3]={x1[0], x1[1], time1},
396
 
    q2[3]={x2[0], x2[1], time2}, q3[3]={x3[0], x3[1], time3},
397
 
    q4[3]={x4[0], x4[1], time4};
398
 
    if(!simplex_intersection3d(k, q0, q1, q2, q3, q4,
399
 
                               &az0, &az1, &az2, &az3, &az4)) return 0;
400
 
    double at0, at1, at2, at3, at4;
401
 
    if(!simplex_intersection3d(k, x0, x1, x2, x3, x4,
402
 
                               &at0, &at1, &at2, &at3, &at4)) return 0;
403
 
    // decide which solution is more accurate for barycentric coordinates
404
 
    double checkx, checky, checkz, checkt;
405
 
    if(k==1){
406
 
        checkx=std::fabs(-ax0*x0[0]+ax1*x1[0]+ax2*x2[0]+ax3*x3[0]+ax4*x4[0])
407
 
        +std::fabs(-ax0*x0[1]+ax1*x1[1]+ax2*x2[1]+ax3*x3[1]+ax4*x4[1])
408
 
        +std::fabs(-ax0*x0[2]+ax1*x1[2]+ax2*x2[2]+ax3*x3[2]+ax4*x4[2])
409
 
        +std::fabs(-ax0*time0+ax1*time1+ax2*time2+ax3*time3+ax4*time4);
410
 
        checky=std::fabs(-ay0*x0[0]+ay1*x1[0]+ay2*x2[0]+ay3*x3[0]+ay4*x4[0])
411
 
        +std::fabs(-ay0*x0[1]+ay1*x1[1]+ay2*x2[1]+ay3*x3[1]+ay4*x4[1])
412
 
        +std::fabs(-ay0*x0[2]+ay1*x1[2]+ay2*x2[2]+ay3*x3[2]+ay4*x4[2])
413
 
        +std::fabs(-ay0*time0+ay1*time1+ay2*time2+ay3*time3+ay4*time4);
414
 
        checkz=std::fabs(-az0*x0[0]+az1*x1[0]+az2*x2[0]+az3*x3[0]+az4*x4[0])
415
 
        +std::fabs(-az0*x0[1]+az1*x1[1]+az2*x2[1]+az3*x3[1]+az4*x4[1])
416
 
        +std::fabs(-az0*x0[2]+az1*x1[2]+az2*x2[2]+az3*x3[2]+az4*x4[2])
417
 
        +std::fabs(-az0*time0+az1*time1+az2*time2+az3*time3+az4*time4);
418
 
        checkt=std::fabs(-at0*x0[0]+at1*x1[0]+at2*x2[0]+at3*x3[0]+at4*x4[0])
419
 
        +std::fabs(-at0*x0[1]+at1*x1[1]+at2*x2[1]+at3*x3[1]+at4*x4[1])
420
 
        +std::fabs(-at0*x0[2]+at1*x1[2]+at2*x2[2]+at3*x3[2]+at4*x4[2])
421
 
        +std::fabs(-at0*time0+at1*time1+at2*time2+at3*time3+at4*time4);
422
 
    }else{
423
 
        checkx=std::fabs(-ax0*x0[0]-ax1*x1[0]+ax2*x2[0]+ax3*x3[0]+ax4*x4[0])
424
 
        +std::fabs(-ax0*x0[1]-ax1*x1[1]+ax2*x2[1]+ax3*x3[1]+ax4*x4[1])
425
 
        +std::fabs(-ax0*x0[2]-ax1*x1[2]+ax2*x2[2]+ax3*x3[2]+ax4*x4[2])
426
 
        +std::fabs(-ax0*time0-ax1*time1+ax2*time2+ax3*time3+ax4*time4);
427
 
        checky=std::fabs(-ay0*x0[0]-ay1*x1[0]+ay2*x2[0]+ay3*x3[0]+ay4*x4[0])
428
 
        +std::fabs(-ay0*x0[1]-ay1*x1[1]+ay2*x2[1]+ay3*x3[1]+ay4*x4[1])
429
 
        +std::fabs(-ay0*x0[2]-ay1*x1[2]+ay2*x2[2]+ay3*x3[2]+ay4*x4[2])
430
 
        +std::fabs(-ay0*time0-ay1*time1+ay2*time2+ay3*time3+ay4*time4);
431
 
        checkz=std::fabs(-az0*x0[0]-az1*x1[0]+az2*x2[0]+az3*x3[0]+az4*x4[0])
432
 
        +std::fabs(-az0*x0[1]-az1*x1[1]+az2*x2[1]+az3*x3[1]+az4*x4[1])
433
 
        +std::fabs(-az0*x0[2]-az1*x1[2]+az2*x2[2]+az3*x3[2]+az4*x4[2])
434
 
        +std::fabs(-az0*time0-az1*time1+az2*time2+az3*time3+az4*time4);
435
 
        checkt=std::fabs(-at0*x0[0]-at1*x1[0]+at2*x2[0]+at3*x3[0]+at4*x4[0])
436
 
        +std::fabs(-at0*x0[1]-at1*x1[1]+at2*x2[1]+at3*x3[1]+at4*x4[1])
437
 
        +std::fabs(-at0*x0[2]-at1*x1[2]+at2*x2[2]+at3*x3[2]+at4*x4[2])
438
 
        +std::fabs(-at0*time0-at1*time1+at2*time2+at3*time3+at4*time4);
439
 
    }
440
 
    if(checkx<=checky && checkx<=checkz && checkx<=checkt){
441
 
        *alpha0=ax0;
442
 
        *alpha1=ax1;
443
 
        *alpha2=ax2;
444
 
        *alpha3=ax3;
445
 
    }else if(checky<=checkz && checky<=checkt){
446
 
        *alpha0=ay0;
447
 
        *alpha1=ay1;
448
 
        *alpha2=ay2;
449
 
        *alpha3=ay3;
450
 
    }else if(checkz<=checkt){
451
 
        *alpha0=az0;
452
 
        *alpha1=az1;
453
 
        *alpha2=az2;
454
 
        *alpha3=az3;
455
 
    }else{
456
 
        *alpha0=at0;
457
 
        *alpha1=at1;
458
 
        *alpha2=at2;
459
 
        *alpha3=at3;
460
 
    }
461
 
    return 1;
462
 
}
463
 
 
464
 
//==============================================================================
465
 
int
466
 
simplex_intersection_time3d(int k,
467
 
                            const double* x0, int t0,
468
 
                            const double* x1, int t1,
469
 
                            const double* x2, int t2,
470
 
                            const double* x3, int t3,
471
 
                            const double* x4, int t4,
472
 
                            const double* x5, int t5,
473
 
                            double* alpha0, 
474
 
                            double* alpha1, 
475
 
                            double* alpha2,
476
 
                            double* alpha3,
477
 
                            double* alpha4,
478
 
                            double* alpha5)
479
 
{
480
 
    assert(1<=k && k<=5);
481
 
    assert(t0==0 || t0==1);
482
 
    assert(t1==0 || t1==1);
483
 
    assert(t2==0 || t2==1);
484
 
    assert(t3==0 || t3==1);
485
 
    assert(t4==0 || t4==1);
486
 
    assert(t5==0 || t5==1);
487
 
    double sum1, sum2;
488
 
    switch(k){
489
 
        case 1: // point vs. pentachoron
490
 
            *alpha1=-orientation_time3d(x0, t0, x2, t2, x3, t3, x4, t4, x5, t5);
491
 
            *alpha2= orientation_time3d(x0, t0, x1, t1, x3, t3, x4, t4, x5, t5);
492
 
            if(!same_sign(*alpha1, *alpha2)) return 0;
493
 
            *alpha3=-orientation_time3d(x0, t0, x1, t1, x2, t3, x4, t4, x5, t5);
494
 
            if(!same_sign(*alpha1, *alpha3)) return 0;
495
 
            *alpha4= orientation_time3d(x0, t0, x1, t1, x2, t2, x3, t3, x5, t5);
496
 
            if(!same_sign(*alpha1, *alpha4)) return 0;
497
 
            *alpha5=-orientation_time3d(x0, t0, x1, t1, x2, t2, x3, t3, x4, t4);
498
 
            if(!same_sign(*alpha1, *alpha5)) return 0;
499
 
            sum2=*alpha1+*alpha2+*alpha3+*alpha4+*alpha5;
500
 
            if(sum2){
501
 
                *alpha0=1;
502
 
                *alpha1/=sum2;
503
 
                *alpha2/=sum2;
504
 
                *alpha3/=sum2;
505
 
                *alpha4/=sum2;
506
 
                *alpha5/=sum2;
507
 
                return 1;
508
 
            }else{
509
 
                if(simplex_intersection_time3d(1, x0, t0, x2, t2, x3, t3, x4, t4,
510
 
                                               x5, t5, alpha0, alpha2, alpha3, alpha4, alpha5)){
511
 
                    *alpha1=0;
512
 
                    return 1;
513
 
                }
514
 
                if(simplex_intersection_time3d(1, x0, t0, x1, t1, x3, t3, x4, t4,
515
 
                                               x5, t5, alpha0, alpha1, alpha3, alpha4, alpha5)){
516
 
                    *alpha2=0;
517
 
                    return 1;
518
 
                }
519
 
                if(simplex_intersection_time3d(1, x0, t0, x1, t1, x2, t2, x4, t4,
520
 
                                               x5, t5, alpha0, alpha1, alpha2, alpha4, alpha5)){
521
 
                    *alpha3=0;
522
 
                    return 1;
523
 
                }
524
 
                if(simplex_intersection_time3d(1, x0, t0, x1, t1, x2, t2, x3, t3,
525
 
                                               x5, t5, alpha0, alpha1, alpha2, alpha3, alpha5)){
526
 
                    *alpha4=0;
527
 
                    return 1;
528
 
                }
529
 
                if(simplex_intersection_time3d(1, x0, t0, x1, t1, x2, t2, x3, t3,
530
 
                                               x4, t4, alpha0, alpha1, alpha2, alpha3, alpha4)){
531
 
                    *alpha5=0;
532
 
                    return 1;
533
 
                }
534
 
                return 0;
535
 
            }
536
 
            
537
 
        case 2: // segment vs. tetrahedron
538
 
            *alpha0= orientation_time3d(x1, t1, x2, t2, x3, t3, x4, t4, x5, t5);
539
 
            *alpha1=-orientation_time3d(x0, t0, x2, t2, x3, t3, x4, t4, x5, t5);
540
 
            if(!same_sign(*alpha0, *alpha1)) return 0;
541
 
            *alpha2= orientation_time3d(x0, t0, x1, t1, x3, t3, x4, t4, x5, t5);
542
 
            *alpha3=-orientation_time3d(x0, t0, x1, t1, x2, t2, x4, t4, x5, t5);
543
 
            if(!same_sign(*alpha2, *alpha3)) return 0;
544
 
            *alpha4= orientation_time3d(x0, t0, x1, t1, x2, t2, x3, t3, x5, t5);
545
 
            if(!same_sign(*alpha2, *alpha4)) return 0;
546
 
            *alpha5=-orientation_time3d(x0, t0, x1, t1, x2, t2, x3, t3, x4, t4);
547
 
            if(!same_sign(*alpha2, *alpha5)) return 0;
548
 
            sum1=*alpha0+*alpha1;
549
 
            sum2=*alpha2+*alpha3+*alpha4+*alpha5;
550
 
            if(sum1 && sum2){
551
 
                *alpha0/=sum1;
552
 
                *alpha1/=sum1;
553
 
                *alpha2/=sum2;
554
 
                *alpha3/=sum2;
555
 
                *alpha4/=sum2;
556
 
                *alpha5/=sum2;
557
 
                return 1;
558
 
            }else{
559
 
                if(simplex_intersection_time3d(1, x1, t1, x2, t2, x3, t3, x4, t4,
560
 
                                               x5, t5, alpha1, alpha2, alpha3, alpha4, alpha5)){
561
 
                    *alpha0=0;
562
 
                    return 1;
563
 
                }
564
 
                if(simplex_intersection_time3d(1, x0, t0, x2, t2, x3, t3, x4, t4,
565
 
                                               x5, t5, alpha0, alpha2, alpha3, alpha4, alpha5)){
566
 
                    *alpha1=0;
567
 
                    return 1;
568
 
                }
569
 
                if(simplex_intersection_time3d(2, x0, t0, x1, t1, x3, t3, x4, t4,
570
 
                                               x5, t5, alpha0, alpha1, alpha3, alpha4, alpha5)){
571
 
                    *alpha2=0;
572
 
                    return 1;
573
 
                }
574
 
                if(simplex_intersection_time3d(2, x0, t0, x1, t1, x2, t2, x4, t4,
575
 
                                               x5, t5, alpha0, alpha1, alpha2, alpha4, alpha5)){
576
 
                    *alpha3=0;
577
 
                    return 1;
578
 
                }
579
 
                if(simplex_intersection_time3d(2, x0, t0, x1, t1, x2, t2, x3, t3,
580
 
                                               x5, t5, alpha0, alpha1, alpha2, alpha3, alpha5)){
581
 
                    *alpha4=0;
582
 
                    return 1;
583
 
                }
584
 
                if(simplex_intersection_time3d(2, x0, t0, x1, t1, x2, t2, x3, t3,
585
 
                                               x4, t4, alpha0, alpha1, alpha2, alpha3, alpha4)){
586
 
                    *alpha5=0;
587
 
                    return 1;
588
 
                }
589
 
                return 0;
590
 
            }
591
 
            
592
 
        case 3: // triangle vs. triangle
593
 
            *alpha0= orientation_time3d(x1, t1, x2, t2, x3, t3, x4, t4, x5, t5);
594
 
            *alpha1=-orientation_time3d(x0, t0, x2, t2, x3, t3, x4, t4, x5, t5);
595
 
            if(!same_sign(*alpha0, *alpha1)) return 0;
596
 
            *alpha2= orientation_time3d(x0, t0, x1, t1, x3, t3, x4, t4, x5, t5);
597
 
            if(!same_sign(*alpha0, *alpha2)) return 0;
598
 
            *alpha3=-orientation_time3d(x0, t0, x1, t1, x2, t2, x4, t4, x5, t5);
599
 
            *alpha4= orientation_time3d(x0, t0, x1, t1, x2, t2, x3, t3, x5, t5);
600
 
            if(!same_sign(*alpha3, *alpha4)) return 0;
601
 
            *alpha5=-orientation_time3d(x0, t0, x1, t1, x2, t2, x3, t3, x4, t4);
602
 
            if(!same_sign(*alpha3, *alpha5)) return 0;
603
 
            sum1=*alpha0+*alpha1+*alpha2;
604
 
            sum2=*alpha3+*alpha4+*alpha5;
605
 
            if(sum1 && sum2){
606
 
                *alpha0/=sum1;
607
 
                *alpha1/=sum1;
608
 
                *alpha2/=sum1;
609
 
                *alpha3/=sum2;
610
 
                *alpha4/=sum2;
611
 
                *alpha5/=sum2;
612
 
                return 1;
613
 
            }else{
614
 
                if(simplex_intersection_time3d(2, x1, t1, x2, t2, x3, t3, x4, t4,
615
 
                                               x5, t5, alpha1, alpha2, alpha3, alpha4, alpha5)){
616
 
                    *alpha0=0;
617
 
                    return 1;
618
 
                }
619
 
                if(simplex_intersection_time3d(2, x0, t0, x2, t2, x3, t3, x4, t4,
620
 
                                               x5, t5, alpha0, alpha2, alpha3, alpha4, alpha5)){
621
 
                    *alpha1=0;
622
 
                    return 1;
623
 
                }
624
 
                if(simplex_intersection_time3d(2, x0, t0, x1, t1, x3, t3, x4, t4,
625
 
                                               x5, t5, alpha0, alpha1, alpha3, alpha4, alpha5)){
626
 
                    *alpha2=0;
627
 
                    return 1;
628
 
                }
629
 
                if(simplex_intersection_time3d(2, x4, t4, x5, t5, x0, t0, x1, t1,
630
 
                                               x2, t2, alpha4, alpha5, alpha0, alpha1, alpha2)){
631
 
                    *alpha3=0;
632
 
                    return 1;
633
 
                }
634
 
                if(simplex_intersection_time3d(2, x3, t3, x5, t5, x0, t0, x1, t1,
635
 
                                               x2, t2, alpha3, alpha5, alpha0, alpha1, alpha2)){
636
 
                    *alpha4=0;
637
 
                    return 1;
638
 
                }
639
 
                if(simplex_intersection_time3d(2, x3, t3, x4, t4, x0, t0, x1, t1,
640
 
                                               x2, t2, alpha3, alpha4, alpha0, alpha1, alpha2)){
641
 
                    *alpha5=0;
642
 
                    return 1;
643
 
                }
644
 
                return 0;
645
 
            }
646
 
            
647
 
        case 4: // tetrahedron vs. segment
648
 
        case 5: // pentachoron vs. point
649
 
            return simplex_intersection_time3d(6-k, x5, t5, x4, t4, x3, t3, x2, t2,
650
 
                                               x1, t1, x0, t0, alpha5, alpha4, alpha3, alpha2, alpha1, alpha0);
651
 
        default:
652
 
            return -1; // should never get here
653
 
    }
654
 
}
655
 
 
656
 
//==============================================================================
657
 
// degenerate test in 4d - assumes five points lie on the same hyper-plane
658
 
static int
659
 
simplex_intersection4d(int k,
660
 
                       const double* x0,
661
 
                       const double* x1,
662
 
                       const double* x2,
663
 
                       const double* x3,
664
 
                       const double* x4,
665
 
                       double* alpha0, 
666
 
                       double* alpha1, 
667
 
                       double* alpha2,
668
 
                       double* alpha3,
669
 
                       double* )
670
 
{
671
 
    assert(k<=2);
672
 
    // try projecting each coordinate out in turn
673
 
    double ax0, ax1, ax2, ax3, ax4;
674
 
    if(!simplex_intersection3d(k, x0+1, x1+1, x2+1, x3+1, x4+1,
675
 
                               &ax0, &ax1, &ax2, &ax3, &ax4)) return 0;
676
 
    double ay0, ay1, ay2, ay3, ay4;
677
 
    double p0[3]={x0[0], x0[2], x0[3]}, p1[3]={x1[0], x1[2], x1[3]},
678
 
    p2[3]={x2[0], x2[2], x2[3]}, p3[3]={x3[0], x3[2], x3[3]},
679
 
    p4[3]={x4[0], x4[2], x4[3]};
680
 
    if(!simplex_intersection3d(k, p0, p1, p2, p3, p4,
681
 
                               &ay0, &ay1, &ay2, &ay3, &ay4)) return 0;
682
 
    double az0, az1, az2, az3, az4;
683
 
    double q0[3]={x0[0], x0[1], x0[3]}, q1[3]={x1[0], x1[1], x1[3]},
684
 
    q2[3]={x2[0], x2[1], x2[3]}, q3[3]={x3[0], x3[1], x3[3]},
685
 
    q4[3]={x4[0], x4[1], x4[3]};
686
 
    if(!simplex_intersection3d(k, q0, q1, q2, q3, q4,
687
 
                               &az0, &az1, &az2, &az3, &az4)) return 0;
688
 
    double at0, at1, at2, at3, at4;
689
 
    if(!simplex_intersection3d(k, x0, x1, x2, x3, x4,
690
 
                               &at0, &at1, &at2, &at3, &at4)) return 0;
691
 
    // decide which solution is more accurate for barycentric coordinates
692
 
    double checkx, checky, checkz, checkt;
693
 
    if(k==1){
694
 
        checkx=std::fabs(-ax0*x0[0]+ax1*x1[0]+ax2*x2[0]+ax3*x3[0]+ax4*x4[0])
695
 
        +std::fabs(-ax0*x0[1]+ax1*x1[1]+ax2*x2[1]+ax3*x3[1]+ax4*x4[1])
696
 
        +std::fabs(-ax0*x0[2]+ax1*x1[2]+ax2*x2[2]+ax3*x3[2]+ax4*x4[2])
697
 
        +std::fabs(-ax0*x0[3]+ax1*x1[3]+ax2*x2[3]+ax3*x3[3]+ax4*x4[3]);
698
 
        checky=std::fabs(-ay0*x0[0]+ay1*x1[0]+ay2*x2[0]+ay3*x3[0]+ay4*x4[0])
699
 
        +std::fabs(-ay0*x0[1]+ay1*x1[1]+ay2*x2[1]+ay3*x3[1]+ay4*x4[1])
700
 
        +std::fabs(-ay0*x0[2]+ay1*x1[2]+ay2*x2[2]+ay3*x3[2]+ay4*x4[2])
701
 
        +std::fabs(-ay0*x0[3]+ay1*x1[3]+ay2*x2[3]+ay3*x3[3]+ay4*x4[3]);
702
 
        checkz=std::fabs(-az0*x0[0]+az1*x1[0]+az2*x2[0]+az3*x3[0]+az4*x4[0])
703
 
        +std::fabs(-az0*x0[1]+az1*x1[1]+az2*x2[1]+az3*x3[1]+az4*x4[1])
704
 
        +std::fabs(-az0*x0[2]+az1*x1[2]+az2*x2[2]+az3*x3[2]+az4*x4[2])
705
 
        +std::fabs(-az0*x0[3]+az1*x1[3]+az2*x2[3]+az3*x3[3]+az4*x4[3]);
706
 
        checkt=std::fabs(-at0*x0[0]+at1*x1[0]+at2*x2[0]+at3*x3[0]+at4*x4[0])
707
 
        +std::fabs(-at0*x0[1]+at1*x1[1]+at2*x2[1]+at3*x3[1]+at4*x4[1])
708
 
        +std::fabs(-at0*x0[2]+at1*x1[2]+at2*x2[2]+at3*x3[2]+at4*x4[2])
709
 
        +std::fabs(-at0*x0[3]+at1*x1[3]+at2*x2[3]+at3*x3[3]+at4*x4[3]);
710
 
    }else{
711
 
        checkx=std::fabs(-ax0*x0[0]-ax1*x1[0]+ax2*x2[0]+ax3*x3[0]+ax4*x4[0])
712
 
        +std::fabs(-ax0*x0[1]-ax1*x1[1]+ax2*x2[1]+ax3*x3[1]+ax4*x4[1])
713
 
        +std::fabs(-ax0*x0[2]-ax1*x1[2]+ax2*x2[2]+ax3*x3[2]+ax4*x4[2])
714
 
        +std::fabs(-ax0*x0[3]-ax1*x1[3]+ax2*x2[3]+ax3*x3[3]+ax4*x4[3]);
715
 
        checky=std::fabs(-ay0*x0[0]-ay1*x1[0]+ay2*x2[0]+ay3*x3[0]+ay4*x4[0])
716
 
        +std::fabs(-ay0*x0[1]-ay1*x1[1]+ay2*x2[1]+ay3*x3[1]+ay4*x4[1])
717
 
        +std::fabs(-ay0*x0[2]-ay1*x1[2]+ay2*x2[2]+ay3*x3[2]+ay4*x4[2])
718
 
        +std::fabs(-ay0*x0[3]-ay1*x1[3]+ay2*x2[3]+ay3*x3[3]+ay4*x4[3]);
719
 
        checkz=std::fabs(-az0*x0[0]-az1*x1[0]+az2*x2[0]+az3*x3[0]+az4*x4[0])
720
 
        +std::fabs(-az0*x0[1]-az1*x1[1]+az2*x2[1]+az3*x3[1]+az4*x4[1])
721
 
        +std::fabs(-az0*x0[2]-az1*x1[2]+az2*x2[2]+az3*x3[2]+az4*x4[2])
722
 
        +std::fabs(-az0*x0[3]-az1*x1[3]+az2*x2[3]+az3*x3[3]+az4*x4[3]);
723
 
        checkt=std::fabs(-at0*x0[0]-at1*x1[0]+at2*x2[0]+at3*x3[0]+at4*x4[0])
724
 
        +std::fabs(-at0*x0[1]-at1*x1[1]+at2*x2[1]+at3*x3[1]+at4*x4[1])
725
 
        +std::fabs(-at0*x0[2]-at1*x1[2]+at2*x2[2]+at3*x3[2]+at4*x4[2])
726
 
        +std::fabs(-at0*x0[3]-at1*x1[3]+at2*x2[3]+at3*x3[3]+at4*x4[3]);
727
 
    }
728
 
    if(checkx<=checky && checkx<=checkz && checkx<=checkt){
729
 
        *alpha0=ax0;
730
 
        *alpha1=ax1;
731
 
        *alpha2=ax2;
732
 
        *alpha3=ax3;
733
 
    }else if(checky<=checkz && checky<=checkt){
734
 
        *alpha0=ay0;
735
 
        *alpha1=ay1;
736
 
        *alpha2=ay2;
737
 
        *alpha3=ay3;
738
 
    }else if(checkz<=checkt){
739
 
        *alpha0=az0;
740
 
        *alpha1=az1;
741
 
        *alpha2=az2;
742
 
        *alpha3=az3;
743
 
    }else{
744
 
        *alpha0=at0;
745
 
        *alpha1=at1;
746
 
        *alpha2=at2;
747
 
        *alpha3=at3;
748
 
    }
749
 
    return 1;
750
 
}
751
 
 
752
 
//==============================================================================
753
 
int
754
 
simplex_intersection4d(int k,
755
 
                       const double* x0,
756
 
                       const double* x1,
757
 
                       const double* x2,
758
 
                       const double* x3,
759
 
                       const double* x4,
760
 
                       const double* x5,
761
 
                       double* alpha0, 
762
 
                       double* alpha1, 
763
 
                       double* alpha2,
764
 
                       double* alpha3,
765
 
                       double* alpha4,
766
 
                       double* alpha5)
767
 
{
768
 
    assert(1<=k && k<=5);
769
 
    double sum1, sum2;
770
 
    switch(k){
771
 
        case 1: // point vs. pentachoron
772
 
            *alpha1=-orientation4d(x0, x2, x3, x4, x5);
773
 
            *alpha2= orientation4d(x0, x1, x3, x4, x5);
774
 
            if(!same_sign(*alpha1, *alpha2)) return 0;
775
 
            *alpha3=-orientation4d(x0, x1, x2, x4, x5);
776
 
            if(!same_sign(*alpha1, *alpha3)) return 0;
777
 
            if(!same_sign(*alpha2, *alpha3)) return 0;
778
 
            *alpha4= orientation4d(x0, x1, x2, x3, x5);
779
 
            if(!same_sign(*alpha1, *alpha4)) return 0;
780
 
            if(!same_sign(*alpha2, *alpha4)) return 0;
781
 
            if(!same_sign(*alpha3, *alpha4)) return 0;
782
 
            *alpha5=-orientation4d(x0, x1, x2, x3, x4);
783
 
            if(!same_sign(*alpha1, *alpha5)) return 0;
784
 
            if(!same_sign(*alpha2, *alpha5)) return 0;
785
 
            if(!same_sign(*alpha3, *alpha5)) return 0;
786
 
            if(!same_sign(*alpha4, *alpha5)) return 0;
787
 
            
788
 
            
789
 
            sum2=*alpha1+*alpha2+*alpha3+*alpha4+*alpha5;
790
 
            if(sum2){
791
 
                *alpha0=1;
792
 
                *alpha1/=sum2;
793
 
                *alpha2/=sum2;
794
 
                *alpha3/=sum2;
795
 
                *alpha4/=sum2;
796
 
                *alpha5/=sum2;
797
 
                return 1;
798
 
            }else{
799
 
                if(simplex_intersection4d(1, x0, x2, x3, x4, x5,
800
 
                                          alpha0, alpha2, alpha3, alpha4, alpha5)){
801
 
                    *alpha1=0;
802
 
                    return 1;
803
 
                }
804
 
                if(simplex_intersection4d(1, x0, x1, x3, x4, x5,
805
 
                                          alpha0, alpha1, alpha3, alpha4, alpha5)){
806
 
                    *alpha2=0;
807
 
                    return 1;
808
 
                }
809
 
                if(simplex_intersection4d(1, x0, x1, x2, x4, x5,
810
 
                                          alpha0, alpha1, alpha2, alpha4, alpha5)){
811
 
                    *alpha3=0;
812
 
                    return 1;
813
 
                }
814
 
                if(simplex_intersection4d(1, x0, x1, x2, x3, x5,
815
 
                                          alpha0, alpha1, alpha2, alpha3, alpha5)){
816
 
                    *alpha4=0;
817
 
                    return 1;
818
 
                }
819
 
                if(simplex_intersection4d(1, x0, x1, x2, x3, x4,
820
 
                                          alpha0, alpha1, alpha2, alpha3, alpha4)){
821
 
                    *alpha5=0;
822
 
                    return 1;
823
 
                }
824
 
                return 0;
825
 
            }
826
 
            
827
 
        case 2: // segment vs. tetrahedron
828
 
            *alpha0= orientation4d(x1, x2, x3, x4, x5);
829
 
            *alpha1=-orientation4d(x0, x2, x3, x4, x5);
830
 
            if(!same_sign(*alpha0, *alpha1)) return 0;
831
 
            *alpha2= orientation4d(x0, x1, x3, x4, x5);
832
 
            *alpha3=-orientation4d(x0, x1, x2, x4, x5);
833
 
            if(!same_sign(*alpha2, *alpha3)) return 0;
834
 
            *alpha4= orientation4d(x0, x1, x2, x3, x5);
835
 
            if(!same_sign(*alpha2, *alpha4)) return 0;
836
 
            if(!same_sign(*alpha3, *alpha4)) return 0;         
837
 
            *alpha5=-orientation4d(x0, x1, x2, x3, x4);
838
 
            if(!same_sign(*alpha2, *alpha5)) return 0;
839
 
            if(!same_sign(*alpha3, *alpha5)) return 0;
840
 
            if(!same_sign(*alpha4, *alpha5)) return 0;         
841
 
            
842
 
            sum1=*alpha0+*alpha1;
843
 
            sum2=*alpha2+*alpha3+*alpha4+*alpha5;
844
 
            if(sum1 && sum2){
845
 
                *alpha0/=sum1;
846
 
                *alpha1/=sum1;
847
 
                *alpha2/=sum2;
848
 
                *alpha3/=sum2;
849
 
                *alpha4/=sum2;
850
 
                *alpha5/=sum2;
851
 
                return 1;
852
 
            }else{
853
 
                if(simplex_intersection4d(1, x1, x2, x3, x4, x5,
854
 
                                          alpha1, alpha2, alpha3, alpha4, alpha5)){
855
 
                    *alpha0=0;
856
 
                    return 1;
857
 
                }
858
 
                if(simplex_intersection4d(1, x0, x2, x3, x4, x5,
859
 
                                          alpha0, alpha2, alpha3, alpha4, alpha5)){
860
 
                    *alpha1=0;
861
 
                    return 1;
862
 
                }
863
 
                if(simplex_intersection4d(2, x0, x1, x3, x4, x5,
864
 
                                          alpha0, alpha1, alpha3, alpha4, alpha5)){
865
 
                    *alpha2=0;
866
 
                    return 1;
867
 
                }
868
 
                if(simplex_intersection4d(2, x0, x1, x2, x4, x5,
869
 
                                          alpha0, alpha1, alpha2, alpha4, alpha5)){
870
 
                    *alpha3=0;
871
 
                    return 1;
872
 
                }
873
 
                if(simplex_intersection4d(2, x0, x1, x2, x3, x5,
874
 
                                          alpha0, alpha1, alpha2, alpha3, alpha5)){
875
 
                    *alpha4=0;
876
 
                    return 1;
877
 
                }
878
 
                if(simplex_intersection4d(2, x0, x1, x2, x3, x4,
879
 
                                          alpha0, alpha1, alpha2, alpha3, alpha4)){
880
 
                    *alpha5=0;
881
 
                    return 1;
882
 
                }
883
 
                return 0;
884
 
            }
885
 
            
886
 
        case 3: // triangle vs. triangle
887
 
            *alpha0= orientation4d(x1, x2, x3, x4, x5);
888
 
            *alpha1=-orientation4d(x0, x2, x3, x4, x5);
889
 
            if(!same_sign(*alpha0, *alpha1)) return 0;
890
 
            *alpha2= orientation4d(x0, x1, x3, x4, x5);
891
 
            if(!same_sign(*alpha0, *alpha2)) return 0;
892
 
            if(!same_sign(*alpha1, *alpha2)) return 0;
893
 
            *alpha3=-orientation4d(x0, x1, x2, x4, x5);
894
 
            *alpha4= orientation4d(x0, x1, x2, x3, x5);
895
 
            if(!same_sign(*alpha3, *alpha4)) return 0;
896
 
            *alpha5=-orientation4d(x0, x1, x2, x3, x4);
897
 
            if(!same_sign(*alpha3, *alpha5)) return 0;
898
 
            if(!same_sign(*alpha4, *alpha5)) return 0;         
899
 
            
900
 
            sum1=*alpha0+*alpha1+*alpha2;
901
 
            sum2=*alpha3+*alpha4+*alpha5;
902
 
            if(sum1 && sum2){
903
 
                *alpha0/=sum1;
904
 
                *alpha1/=sum1;
905
 
                *alpha2/=sum1;
906
 
                *alpha3/=sum2;
907
 
                *alpha4/=sum2;
908
 
                *alpha5/=sum2;
909
 
                return 1;
910
 
            }else{
911
 
                if(simplex_intersection4d(2, x1, x2, x3, x4, x5,
912
 
                                          alpha1, alpha2, alpha3, alpha4, alpha5)){
913
 
                    *alpha0=0;
914
 
                    return 1;
915
 
                }
916
 
                if(simplex_intersection4d(2, x0, x2, x3, x4, x5,
917
 
                                          alpha0, alpha2, alpha3, alpha4, alpha5)){
918
 
                    *alpha1=0;
919
 
                    return 1;
920
 
                }
921
 
                if(simplex_intersection4d(2, x0, x1, x3, x4, x5,
922
 
                                          alpha0, alpha1, alpha3, alpha4, alpha5)){
923
 
                    *alpha2=0;
924
 
                    return 1;
925
 
                }
926
 
                if(simplex_intersection4d(2, x4, x5, x0, x1, x2,
927
 
                                          alpha4, alpha5, alpha0, alpha1, alpha2)){
928
 
                    *alpha3=0;
929
 
                    return 1;
930
 
                }
931
 
                if(simplex_intersection4d(2, x3, x5, x0, x1, x2,
932
 
                                          alpha3, alpha5, alpha0, alpha1, alpha2)){
933
 
                    *alpha4=0;
934
 
                    return 1;
935
 
                }
936
 
                if(simplex_intersection4d(2, x3, x4, x0, x1, x2,
937
 
                                          alpha3, alpha4, alpha0, alpha1, alpha2)){
938
 
                    *alpha5=0;
939
 
                    return 1;
940
 
                }
941
 
                return 0;
942
 
            }
943
 
            
944
 
        case 4: // tetrahedron vs. segment
945
 
        case 5: // pentachoron vs. point
946
 
            return simplex_intersection4d(6-k, x5, x4, x3, x2, x1, x0,
947
 
                                          alpha5, alpha4, alpha3, alpha2, alpha1, alpha0);
948
 
        default:
949
 
            return -1; // should never get here
950
 
    }
951
 
}