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