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