1 package org.opentrafficsim.core.geometry;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 public class Fresnel
20 {
21
22
23
24 private static double[] CN1 = new double[] {
25 9.999999999999999421E-01,
26 -1.994608988261842706E-01,
27 1.761939525434914045E-02,
28 -5.280796513726226960E-04,
29 5.477113856826871660E-06
30 };
31
32
33 private static double[] CD1 = new double[] {
34 1.000000000000000000E+00,
35 4.727921120104532689E-02,
36 1.099572150256418851E-03,
37 1.552378852769941331E-05,
38 1.189389014228757184E-07
39 };
40
41
42 private static double[] CN2 = new double[] {
43 1.00000000000111043640E+00,
44 -2.07073360335323894245E-01,
45 1.91870279431746926505E-02,
46 -6.71376034694922109230E-04,
47 1.02365435056105864908E-05,
48 -5.68293310121870728343E-08
49 };
50
51
52 private static double[] CD2 = new double[] {
53 1.00000000000000000000E+00,
54 3.96667496952323433510E-02,
55 7.88905245052359907842E-04,
56 1.01344630866749406081E-05,
57 8.77945377892369265356E-08,
58 4.41701374065009620393E-10
59 };
60
61
62 private static double[] SN1 = new double[] {
63 5.2359877559829887021E-01,
64 -7.0748991514452302596E-02,
65 3.8778212346368287939E-03,
66 -8.4555728435277680591E-05,
67 6.7174846662514086196E-07
68 };
69
70
71 private static double[] SD1 = new double[] {
72 1.0000000000000000000E+00,
73 4.1122315114238422205E-02,
74 8.1709194215213447204E-04,
75 9.6269087593903403370E-06,
76 5.9528122767840998345E-08
77 };
78
79
80 private static double[] SN2 = new double[] {
81 5.23598775598344165913E-01,
82 -7.37766914010191323867E-02,
83 4.30730526504366510217E-03,
84 -1.09540023911434994566E-04,
85 1.28531043742724820610E-06,
86 -5.76765815593088804567E-09
87 };
88
89
90 private static double[] SD2 = new double[] {
91 1.00000000000000000000E+00,
92 3.53398342167472162540E-02,
93 6.18224620195473216538E-04,
94 6.87086265718620117905E-06,
95 5.03090581246612375866E-08,
96 2.05539124458579596075E-10
97 };
98
99
100 private static double[] FN3 = new double[] {
101 3.1830975293580985290E-01,
102 1.2226000551672961219E+01,
103 1.2924886131901657025E+02,
104 4.3886367156695547655E+02,
105 4.1466722177958961672E+02,
106 5.6771463664185116454E+01
107 };
108
109
110 private static double[] FD3 = new double[] {
111 1.0000000000000000000E+00,
112 3.8713003365583442831E+01,
113 4.1674359830705629745E+02,
114 1.4740030733966610568E+03,
115 1.5371675584895759916E+03,
116 2.9113088788847831515E+02
117 };
118
119
120 private static double[] FN4 = new double[] {
121 3.183098818220169217E-01,
122 1.958839410219691002E+01,
123 3.398371349269842400E+02,
124 1.930076407867157531E+03,
125 3.091451615744296552E+03,
126 7.177032493651399590E+02
127 };
128
129
130 private static double[] FD4 = new double[] {
131 1.000000000000000000E+00,
132 6.184271381728873709E+01,
133 1.085350675006501251E+03,
134 6.337471558511437898E+03,
135 1.093342489888087888E+04,
136 3.361216991805511494E+03
137 };
138
139
140 private static double[] FN5 = new double[] {
141 -9.675460329952532343E-02,
142 -2.431275407194161683E+01,
143 -1.947621998306889176E+03,
144 -6.059852197160773639E+04,
145 -7.076806952837779823E+05,
146 -2.417656749061154155E+06,
147 -7.834914590078311336E+05
148 };
149
150
151 private static double[] FD5 = new double[] {
152 1.000000000000000000E+00,
153 2.548289012949732752E+02,
154 2.099761536857815105E+04,
155 6.924122509827708985E+05,
156 9.178823229918143780E+06,
157 4.292733255630186679E+07,
158 4.803294184260528342E+07
159 };
160
161
162 private static double[] GN3 = new double[] {
163 1.013206188102747985E-01,
164 4.445338275505123778E+00,
165 5.311228134809894481E+01,
166 1.991828186789025318E+02,
167 1.962320379716626191E+02,
168 2.054214324985006303E+01
169 };
170
171
172 private static double[] GD3 = new double[] {
173 1.000000000000000000E+00,
174 4.539250196736893605E+01,
175 5.835905757164290666E+02,
176 2.544731331818221034E+03,
177 3.481121478565452837E+03,
178 1.013794833960028555E+03
179 };
180
181
182 private static double[] GN4 = new double[] {
183 1.01321161761804586E-01,
184 7.11205001789782823E+00,
185 1.40959617911315524E+02,
186 9.08311749529593938E+02,
187 1.59268006085353864E+03,
188 3.13330163068755950E+02
189 };
190
191
192 private static double[] GD4 = new double[] {
193 1.00000000000000000E+00,
194 7.17128596939302198E+01,
195 1.49051922797329229E+03,
196 1.06729678030583897E+04,
197 2.41315567213369742E+04,
198 1.15149832376260604E+04
199 };
200
201
202 private static double[] GN5 = new double[] {
203 -1.53989733819769316E-01,
204 -4.31710157823357568E+01,
205 -3.87754141746378493E+03,
206 -1.35678867813756347E+05,
207 -1.77758950838029676E+06,
208 -6.66907061668636416E+06,
209 -1.72590224654836845E+06
210 };
211
212
213 private static double[] GD5 = new double[] {
214 1.00000000000000000E+00,
215 2.86733194975899483E+02,
216 2.69183180396242536E+04,
217 1.02878693056687506E+06,
218 1.62095600500231646E+07,
219 9.38695862531635179E+07,
220 1.40622441123580005E+08
221 };
222
223
224
225 private Fresnel()
226 {
227
228 }
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243 public static double[] fresnel(final double x)
244 {
245 final double t = Math.abs(x);
246 double cc, ss;
247 if (t < 1.2)
248 {
249 cc = t * ratioEval(t, CN1, +1) / ratioEval(t, CD1, +1);
250 ss = t * t * t * ratioEval(t, SN1, +1) / ratioEval(t, SD1, +1);
251 }
252 else if (t < 1.6)
253 {
254 cc = t * ratioEval(t, CN2, +1) / ratioEval(t, CD2, +1);
255 ss = t * t * t * ratioEval(t, SN2, +1) / ratioEval(t, SD2, +1);
256 }
257 else if (t < 1.9)
258 {
259 double pitt2 = Math.PI * t * t / 2;
260 double sinpitt2 = Math.sin(pitt2);
261 double cospitt2 = Math.cos(pitt2);
262 double ft = (1 / t) * ratioEval(t, FN3, -1) / ratioEval(t, FD3, -1);
263 double gt = (1 / (t * t * t)) * ratioEval(t, GN3, -1) / ratioEval(t, GD3, -1);
264 cc = .5 + ft * sinpitt2 - gt * cospitt2;
265 ss = .5 - ft * cospitt2 - gt * sinpitt2;
266 }
267 else if (t < 2.4)
268 {
269 double pitt2 = Math.PI * t * t / 2;
270 double sinpitt2 = Math.sin(pitt2);
271 double cospitt2 = Math.cos(pitt2);
272 double tinv = 1 / t;
273 double tttinv = tinv * tinv * tinv;
274 double ft = tinv * ratioEval(t, FN4, -1) / ratioEval(t, FD4, -1);
275 double gt = tttinv * ratioEval(t, GN4, -1) / ratioEval(t, GD4, -1);
276 cc = .5 + ft * sinpitt2 - gt * cospitt2;
277 ss = .5 - ft * cospitt2 - gt * sinpitt2;
278 }
279 else
280 {
281 double pitt2 = Math.PI * t * t / 2;
282 double sinpitt2 = Math.sin(pitt2);
283 double cospitt2 = Math.cos(pitt2);
284 double piinv = 1 / Math.PI;
285 double tinv = 1 / t;
286 double tttinv = tinv * tinv * tinv;
287 double ttttinv = tttinv * tinv;
288 double ft = tinv * (piinv + (ttttinv * ratioEval(t, FN5, -1) / ratioEval(t, FD5, -1)));
289 double gt = tttinv * ((piinv * piinv) + (ttttinv * ratioEval(t, GN5, -1) / ratioEval(t, GD5, -1)));
290 cc = .5 + ft * sinpitt2 - gt * cospitt2;
291 ss = .5 - ft * cospitt2 - gt * sinpitt2;
292 }
293 if (x < 0)
294 {
295 cc = -cc;
296 ss = -ss;
297 }
298
299 return new double[] {cc, ss};
300 }
301
302
303
304
305
306
307
308
309 private static double ratioEval(final double t, final double[] coef, final double sign)
310 {
311 double value = 0;
312 for (int s = 0; s < coef.length; s++)
313 {
314 value += coef[s] * Math.pow(t, sign * 4 * s);
315 }
316 return value;
317 }
318
319 }