Subversion Repositories gelsvn

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
290 jrf 1
#include "verification.h"
2
 
3
using namespace CGLA;
4
using namespace std;
5
 
291 jrf 6
namespace Geometry
7
{
8
 
290 jrf 9
float SqrDistance (const Vec3f& rkPoint,const Triangle& rkTri)
10
{
11
    Vec3f kDiff = rkTri.get_v0() - rkPoint;
12
    double fA00 = sqr_length(rkTri.get_edge(0));
13
    double fA01 = dot(rkTri.get_edge(0),-rkTri.get_edge(2));
14
    double fA11 = sqr_length(rkTri.get_edge(2));
15
    double fB0 = dot(kDiff,rkTri.get_edge(0));
16
    double fB1 = dot(kDiff,-rkTri.get_edge(2));
17
    double fC = sqr_length(kDiff);
18
    double fDet = fabs(fA00*fA11-fA01*fA01);
19
    double fS = fA01*fB1-fA11*fB0;
20
    double fT = fA01*fB0-fA00*fB1;
21
    double fSqrDist;
22
 
23
    if ( fS + fT <= fDet )
24
    {
25
        if ( fS < (double)0.0 )
26
        {
27
            if ( fT < (double)0.0 )  // region 4
28
            {
29
                if ( fB0 < (double)0.0 )
30
                {
31
                    fT = (double)0.0;
32
                    if ( -fB0 >= fA00 )
33
                    {
34
                        fS = (double)1.0;
35
                        fSqrDist = fA00+((double)2.0)*fB0+fC;
36
                    }
37
                    else
38
                    {
39
                        fS = -fB0/fA00;
40
                        fSqrDist = fB0*fS+fC;
41
                    }
42
                }
43
                else
44
                {
45
                    fS = (double)0.0;
46
                    if ( fB1 >= (double)0.0 )
47
                    {
48
                        fT = (double)0.0;
49
                        fSqrDist = fC;
50
                    }
51
                    else if ( -fB1 >= fA11 )
52
                    {
53
                        fT = (double)1.0;
54
                        fSqrDist = fA11+((double)2.0)*fB1+fC;
55
                    }
56
                    else
57
                    {
58
                        fT = -fB1/fA11;
59
                        fSqrDist = fB1*fT+fC;
60
                    }
61
                }
62
            }
63
            else  // region 3
64
            {
65
                fS = (double)0.0;
66
                if ( fB1 >= (double)0.0 )
67
                {
68
                    fT = (double)0.0;
69
                    fSqrDist = fC;
70
                }
71
                else if ( -fB1 >= fA11 )
72
                {
73
                    fT = (double)1.0;
74
                    fSqrDist = fA11+((double)2.0)*fB1+fC;
75
                }
76
                else
77
                {
78
                    fT = -fB1/fA11;
79
                    fSqrDist = fB1*fT+fC;
80
                }
81
            }
82
        }
83
        else if ( fT < (double)0.0 )  // region 5
84
        {
85
            fT = (double)0.0;
86
            if ( fB0 >= (double)0.0 )
87
            {
88
                fS = (double)0.0;
89
                fSqrDist = fC;
90
            }
91
            else if ( -fB0 >= fA00 )
92
            {
93
                fS = (double)1.0;
94
                fSqrDist = fA00+((double)2.0)*fB0+fC;
95
            }
96
            else
97
            {
98
                fS = -fB0/fA00;
99
                fSqrDist = fB0*fS+fC;
100
            }
101
        }
102
        else  // region 0
103
        {
104
            // minimum at interior point
105
            double fInvDet = ((double)1.0)/fDet;
106
            fS *= fInvDet;
107
            fT *= fInvDet;
108
            fSqrDist = fS*(fA00*fS+fA01*fT+((double)2.0)*fB0) +
109
                fT*(fA01*fS+fA11*fT+((double)2.0)*fB1)+fC;
110
        }
111
    }
112
    else
113
    {
114
        double fTmp0, fTmp1, fNumer, fDenom;
115
 
116
        if ( fS < (double)0.0 )  // region 2
117
        {
118
            fTmp0 = fA01 + fB0;
119
            fTmp1 = fA11 + fB1;
120
            if ( fTmp1 > fTmp0 )
121
            {
122
                fNumer = fTmp1 - fTmp0;
123
                fDenom = fA00-2.0f*fA01+fA11;
124
                if ( fNumer >= fDenom )
125
                {
126
                    fS = (double)1.0;
127
                    fT = (double)0.0;
128
                    fSqrDist = fA00+((double)2.0)*fB0+fC;
129
                }
130
                else
131
                {
132
                    fS = fNumer/fDenom;
133
                    fT = (double)1.0 - fS;
134
                    fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) +
135
                        fT*(fA01*fS+fA11*fT+((double)2.0)*fB1)+fC;
136
                }
137
            }
138
            else
139
            {
140
                fS = (double)0.0;
141
                if ( fTmp1 <= (double)0.0 )
142
                {
143
                    fT = (double)1.0;
144
                    fSqrDist = fA11+((double)2.0)*fB1+fC;
145
                }
146
                else if ( fB1 >= (double)0.0 )
147
                {
148
                    fT = (double)0.0;
149
                    fSqrDist = fC;
150
                }
151
                else
152
                {
153
                    fT = -fB1/fA11;
154
                    fSqrDist = fB1*fT+fC;
155
                }
156
            }
157
        }
158
        else if ( fT < (double)0.0 )  // region 6
159
        {
160
            fTmp0 = fA01 + fB1;
161
            fTmp1 = fA00 + fB0;
162
            if ( fTmp1 > fTmp0 )
163
            {
164
                fNumer = fTmp1 - fTmp0;
165
                fDenom = fA00-((double)2.0)*fA01+fA11;
166
                if ( fNumer >= fDenom )
167
                {
168
                    fT = (double)1.0;
169
                    fS = (double)0.0;
170
                    fSqrDist = fA11+((double)2.0)*fB1+fC;
171
                }
172
                else
173
                {
174
                    fT = fNumer/fDenom;
175
                    fS = (double)1.0 - fT;
176
                    fSqrDist = fS*(fA00*fS+fA01*fT+((double)2.0)*fB0) +
177
                        fT*(fA01*fS+fA11*fT+((double)2.0)*fB1)+fC;
178
                }
179
            }
180
            else
181
            {
182
                fT = (double)0.0;
183
                if ( fTmp1 <= (double)0.0 )
184
                {
185
                    fS = (double)1.0;
186
                    fSqrDist = fA00+((double)2.0)*fB0+fC;
187
                }
188
                else if ( fB0 >= (double)0.0 )
189
                {
190
                    fS = (double)0.0;
191
                    fSqrDist = fC;
192
                }
193
                else
194
                {
195
                    fS = -fB0/fA00;
196
                    fSqrDist = fB0*fS+fC;
197
                }
198
            }
199
        }
200
        else  // region 1
201
        {
202
            fNumer = fA11 + fB1 - fA01 - fB0;
203
            if ( fNumer <= (double)0.0 )
204
            {
205
                fS = (double)0.0;
206
                fT = (double)1.0;
207
                fSqrDist = fA11+((double)2.0)*fB1+fC;
208
            }
209
            else
210
            {
211
                fDenom = fA00-2.0f*fA01+fA11;
212
                if ( fNumer >= fDenom )
213
                {
214
                    fS = (double)1.0;
215
                    fT = (double)0.0;
216
                    fSqrDist = fA00+((double)2.0)*fB0+fC;
217
                }
218
                else
219
                {
220
                    fS = fNumer/fDenom;
221
                    fT = (double)1.0 - fS;
222
                    fSqrDist = fS*(fA00*fS+fA01*fT+((double)2.0)*fB0) +
223
                        fT*(fA01*fS+fA11*fT+((double)2.0)*fB1)+fC;
224
                }
225
            }
226
        }
227
    }
228
    return fabs(fSqrDist);
229
}
291 jrf 230
 
231
}