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