1 /**
2  * Contains various interpolation functions.
3  * 
4  * @author Kai Burjack
5  */
6 module doml.interpolation_d;
7 
8 import doml.vector_2d;
9 import doml.vector_3d;
10 
11 /*
12  * The MIT License
13  *
14  * Copyright (c) 2015-2021 Kai Burjack
15  @#$@# Translated by jordan4ibanez
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining a copy
18  * of this software and associated documentation files (the "Software"), to deal
19  * in the Software without restriction, including without limitation the rights
20  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21  * copies of the Software, and to permit persons to whom the Software is
22  * furnished to do so, subject to the following conditions:
23  *
24  * The above copyright notice and this permission notice shall be included in
25  * all copies or substantial portions of the Software.
26  *
27  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33  * THE SOFTWARE.
34  */
35 
36 /**
37  * Contains various interpolation functions.
38  * 
39  * @author Kai Burjack
40  */
41 
42 /**
43     * Bilinearly interpolate the single scalar value <i>f</i> over the given triangle.
44     * <p>
45     * Reference: <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">https://en.wikipedia.org/</a>
46     * 
47     * @param v0X
48     *            the x coordinate of the first triangle vertex
49     * @param v0Y
50     *            the y coordinate of the first triangle vertex
51     * @param f0
52     *            the value of <i>f</i> at the first vertex
53     * @param v1X
54     *            the x coordinate of the second triangle vertex
55     * @param v1Y
56     *            the y coordinate of the second triangle vertex
57     * @param f1
58     *            the value of <i>f</i> at the second vertex
59     * @param v2X
60     *            the x coordinate of the third triangle vertex
61     * @param v2Y
62     *            the y coordinate of the third triangle vertex
63     * @param f2
64     *            the value of <i>f</i> at the third vertex
65     * @param x
66     *            the x coordinate of the point to interpolate <i>f</i> at
67     * @param y
68     *            the y coordinate of the point to interpolate <i>f</i> at
69     * @return the interpolated value of <i>f</i>
70     */
71 public static double interpolateTriangle(
72         double v0X, double v0Y, double f0,
73         double v1X, double v1Y, double f1,
74         double v2X, double v2Y, double f2,
75         double x, double y) {
76     double v12Y = v1Y - v2Y;
77     double v21X = v2X - v1X;
78     double v02X = v0X - v2X;
79     double yv2Y = y - v2Y;
80     double xv2X = x - v2X;
81     double v02Y = v0Y - v2Y;
82     double invDen = 1.0 / (v12Y * v02X + v21X * v02Y);
83     double l1 = (v12Y * xv2X + v21X * yv2Y) * invDen;
84     double l2 = (v02X * yv2Y - v02Y * xv2X) * invDen;
85     return l1 * f0 + l2 * f1 + (1.0f - l1 - l2) * f2;
86 }
87 
88 /**
89     * Bilinearly interpolate the two-dimensional vector <i>f</i> over the given triangle and store the result in <code>dest</code>.
90     * <p>
91     * Reference: <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">https://en.wikipedia.org/</a>
92     * 
93     * @param v0X
94     *            the x coordinate of the first triangle vertex
95     * @param v0Y
96     *            the y coordinate of the first triangle vertex
97     * @param f0X
98     *            the x component of the value of <i>f</i> at the first vertex
99     * @param f0Y
100     *            the y component of the value of <i>f</i> at the first vertex
101     * @param v1X
102     *            the x coordinate of the second triangle vertex
103     * @param v1Y
104     *            the y coordinate of the second triangle vertex
105     * @param f1X
106     *            the x component of the value of <i>f</i> at the second vertex
107     * @param f1Y
108     *            the y component of the value of <i>f</i> at the second vertex
109     * @param v2X
110     *            the x coordinate of the third triangle vertex
111     * @param v2Y
112     *            the y coordinate of the third triangle vertex
113     * @param f2X
114     *            the x component of the value of <i>f</i> at the third vertex
115     * @param f2Y
116     *            the y component of the value of <i>f</i> at the third vertex
117     * @param x
118     *            the x coordinate of the point to interpolate <i>f</i> at
119     * @param y
120     *            the y coordinate of the point to interpolate <i>f</i> at
121     * @param dest
122     *            will hold the interpolation result
123     * @return dest
124     */
125 public static Vector2d interpolateTriangle(
126         double v0X, double v0Y, double f0X, double f0Y,
127         double v1X, double v1Y, double f1X, double f1Y,
128         double v2X, double v2Y, double f2X, double f2Y,
129         double x, double y, Vector2d dest) {
130     double v12Y = v1Y - v2Y;
131     double v21X = v2X - v1X;
132     double v02X = v0X - v2X;
133     double yv2Y = y - v2Y;
134     double xv2X = x - v2X;
135     double v02Y = v0Y - v2Y;
136     double invDen = 1.0 / (v12Y * v02X + v21X * v02Y);
137     double l1 = (v12Y * xv2X + v21X * yv2Y) * invDen;
138     double l2 = (v02X * yv2Y - v02Y * xv2X) * invDen;
139     double l3 = 1.0 - l1 - l2;
140     dest.x = l1 * f0X + l2 * f1X + l3 * f2X;
141     dest.y = l1 * f0Y + l2 * f1Y + l3 * f2Y;
142     return dest;
143 }
144 
145 /**
146     * Compute the first-order derivative of a linear two-dimensional function <i>f</i> with respect to X
147     * and store the result in <code>dest</code>.
148     * <p>
149     * This method computes the constant rate of change for <i>f</i> given the three values of <i>f</i>
150     * at the specified three inputs <code>(v0X, v0Y)</code>, <code>(v1X, v1Y)</code> and <code>(v2X, v2Y)</code>.
151     * 
152     * @param v0X
153     *            the x coordinate of the first triangle vertex
154     * @param v0Y
155     *            the y coordinate of the first triangle vertex
156     * @param f0X
157     *            the x component of the value of <i>f</i> at the first vertex
158     * @param f0Y
159     *            the y component of the value of <i>f</i> at the first vertex
160     * @param v1X
161     *            the x coordinate of the second triangle vertex
162     * @param v1Y
163     *            the y coordinate of the second triangle vertex
164     * @param f1X
165     *            the x component of the value of <i>f</i> at the second vertex
166     * @param f1Y
167     *            the y component of the value of <i>f</i> at the second vertex
168     * @param v2X
169     *            the x coordinate of the third triangle vertex
170     * @param v2Y
171     *            the y coordinate of the third triangle vertex
172     * @param f2X
173     *            the x component of the value of <i>f</i> at the third vertex
174     * @param f2Y
175     *            the y component of the value of <i>f</i> at the third vertex
176     * @param dest
177     *            will hold the result
178     * @return dest
179     */
180 public static Vector2d dFdxLinear(
181         double v0X, double v0Y, double f0X, double f0Y,
182         double v1X, double v1Y, double f1X, double f1Y,
183         double v2X, double v2Y, double f2X, double f2Y, ref Vector2d dest) {
184     double v12Y = v1Y - v2Y;
185     double v02Y = v0Y - v2Y;
186     double den = v12Y * (v0X - v2X) + (v2X - v1X) * v02Y;
187     double l3_1 = den - v12Y + v02Y;
188     double invDen = 1.0f / den;
189     dest.x = invDen * (v12Y * f0X - v02Y * f1X + l3_1 * f2X) - f2X;
190     dest.y = invDen * (v12Y * f0Y - v02Y * f1Y + l3_1 * f2Y) - f2Y;
191     return dest;
192 }
193 
194 /**
195     * Compute the first-order derivative of a linear two-dimensional function <i>f</i> with respect to Y
196     * and store the result in <code>dest</code>.
197     * <p>
198     * This method computes the constant rate of change for <i>f</i> given the three values of <i>f</i>
199     * at the specified three inputs <code>(v0X, v0Y)</code>, <code>(v1X, v1Y)</code> and <code>(v2X, v2Y)</code>.
200     * 
201     * @param v0X
202     *            the x coordinate of the first triangle vertex
203     * @param v0Y
204     *            the y coordinate of the first triangle vertex
205     * @param f0X
206     *            the x component of the value of <i>f</i> at the first vertex
207     * @param f0Y
208     *            the y component of the value of <i>f</i> at the first vertex
209     * @param v1X
210     *            the x coordinate of the second triangle vertex
211     * @param v1Y
212     *            the y coordinate of the second triangle vertex
213     * @param f1X
214     *            the x component of the value of <i>f</i> at the second vertex
215     * @param f1Y
216     *            the y component of the value of <i>f</i> at the second vertex
217     * @param v2X
218     *            the x coordinate of the third triangle vertex
219     * @param v2Y
220     *            the y coordinate of the third triangle vertex
221     * @param f2X
222     *            the x component of the value of <i>f</i> at the third vertex
223     * @param f2Y
224     *            the y component of the value of <i>f</i> at the third vertex
225     * @param dest
226     *            will hold the result
227     * @return dest
228     */
229 public static Vector2d dFdyLinear(
230         double v0X, double v0Y, double f0X, double f0Y,
231         double v1X, double v1Y, double f1X, double f1Y,
232         double v2X, double v2Y, double f2X, double f2Y,
233         ref Vector2d dest) {
234     double v21X = v2X - v1X;
235     double v02X = v0X - v2X;
236     double den = (v1Y - v2Y) * v02X + v21X * (v0Y - v2Y);
237     double l3_1 = den - v21X - v02X;
238     double invDen = 1.0f / den;
239     dest.x = invDen * (v21X * f0X + v02X * f1X + l3_1 * f2X) - f2X;
240     dest.y = invDen * (v21X * f0Y + v02X * f1Y + l3_1 * f2Y) - f2Y;
241     return dest;
242 }
243 
244 /**
245     * Bilinearly interpolate the three-dimensional vector <i>f</i> over the given triangle and store the result in <code>dest</code>.
246     * <p>
247     * Reference: <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">https://en.wikipedia.org/</a>
248     * 
249     * @param v0X
250     *            the x coordinate of the first triangle vertex
251     * @param v0Y
252     *            the y coordinate of the first triangle vertex
253     * @param f0X
254     *            the x component of the value of <i>f</i> at the first vertex
255     * @param f0Y
256     *            the y component of the value of <i>f</i> at the first vertex
257     * @param f0Z
258     *            the z component of the value of <i>f</i> at the first vertex
259     * @param v1X
260     *            the x coordinate of the second triangle vertex
261     * @param v1Y
262     *            the y coordinate of the second triangle vertex
263     * @param f1X
264     *            the x component of the value of <i>f</i> at the second vertex
265     * @param f1Y
266     *            the y component of the value of <i>f</i> at the second vertex
267     * @param f1Z
268     *            the z component of the value of <i>f</i> at the second vertex
269     * @param v2X
270     *            the x coordinate of the third triangle vertex
271     * @param v2Y
272     *            the y coordinate of the third triangle vertex
273     * @param f2X
274     *            the x component of the value of <i>f</i> at the third vertex
275     * @param f2Y
276     *            the y component of the value of <i>f</i> at the third vertex
277     * @param f2Z
278     *            the z component of the value of <i>f</i> at the third vertex
279     * @param x
280     *            the x coordinate of the point to interpolate <i>f</i> at
281     * @param y
282     *            the y coordinate of the point to interpolate <i>f</i> at
283     * @param dest
284     *            will hold the interpolation result
285     * @return dest
286     */
287 public static Vector3d interpolateTriangle(
288         double v0X, double v0Y, double f0X, double f0Y, double f0Z,
289         double v1X, double v1Y, double f1X, double f1Y, double f1Z,
290         double v2X, double v2Y, double f2X, double f2Y, double f2Z,
291         double x, double y, Vector3d dest) {
292     // compute interpolation factors
293     Vector3d t = dest;
294     interpolationFactorsTriangle(v0X, v0Y, v1X, v1Y, v2X, v2Y, x, y, t);
295     // interpolate using these factors
296     return dest.set(t.x * f0X + t.y * f1X + t.z * f2X,
297                     t.x * f0Y + t.y * f1Y + t.z * f2Y,
298                     t.x * f0Z + t.y * f1Z + t.z * f2Z);
299 }
300 
301 /**
302     * Compute the interpolation factors <code>(t0, t1, t2)</code> in order to interpolate an arbitrary value over a given 
303     * triangle at the given point <code>(x, y)</code>.
304     * <p>
305     * This method takes in the 2D vertex positions of the three vertices of a triangle and stores in <code>dest</code> the 
306     * factors <code>(t0, t1, t2)</code> in the equation <code>v' = v0 * t0 + v1 * t1 + v2 * t2</code> where <code>(v0, v1, v2)</code> are
307     * arbitrary (scalar or vector) values associated with the respective vertices of the triangle. The computed value <code>v'</code>
308     * is the interpolated value at the given position <code>(x, y)</code>.
309     * 
310     * @param v0X
311     *            the x coordinate of the first triangle vertex
312     * @param v0Y
313     *            the y coordinate of the first triangle vertex
314     * @param v1X
315     *            the x coordinate of the second triangle vertex
316     * @param v1Y
317     *            the y coordinate of the second triangle vertex
318     * @param v2X
319     *            the x coordinate of the third triangle vertex
320     * @param v2Y
321     *            the y coordinate of the third triangle vertex
322     * @param x
323     *            the x coordinate of the point to interpolate at
324     * @param y
325     *            the y coordinate of the point to interpolate at
326     * @param dest
327     *            will hold the interpolation factors <code>(t0, t1, t2)</code>
328     * @return dest
329     */
330 public static Vector3d interpolationFactorsTriangle(
331         double v0X, double v0Y, double v1X, double v1Y, double v2X, double v2Y,
332         double x, double y, Vector3d dest) {
333     double v12Y = v1Y - v2Y;
334     double v21X = v2X - v1X;
335     double v02X = v0X - v2X;
336     double yv2Y = y - v2Y;
337     double xv2X = x - v2X;
338     double v02Y = v0Y - v2Y;
339     double invDen = 1.0 / (v12Y * v02X + v21X * v02Y);
340     dest.x = (v12Y * xv2X + v21X * yv2Y) * invDen;
341     dest.y = (v02X * yv2Y - v02Y * xv2X) * invDen;
342     dest.z = 1.0 - dest.x - dest.y;
343     return dest;
344 }
345