f806c5829b
* pre-commit: Update and enable clang-format check There is newer version from clang-format so use that. We do not yet want 18 as that is little bit too new. * Format some thing by hand which clang-format "breaks" Clang-format will format some things little bit off in some cases. Format some things by hand so we get cleaner end result. * Run clang-format with ``` pre-commit run --all-files clang-format ``` We have already in previously checked places where clang-format does not make good format and ignored those (hopefully most of the things). --------- Co-authored-by: Kari Argillander <kari.argillander@fidelix.com>
90 lines
3.0 KiB
C
90 lines
3.0 KiB
C
/**
|
|
* @file
|
|
* @brief Performs linear interpolation using single precision floating
|
|
* point math or integer math, or a mixture of both. Linear interpolation
|
|
* is a method of constructing new data points within the range of a discrete
|
|
* set of known data points.
|
|
* @author Steve Karg <skarg@users.sourceforge.net>
|
|
* @date 2011
|
|
* @copyright SPDX-License-Identifier: MIT
|
|
*/
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include "bacnet/basic/sys/linear.h"
|
|
|
|
/**
|
|
* Linearly Interpolate the values between y1 and y3 based on x.
|
|
*
|
|
* @param x1 - first x value, where x1 <= x2 <= x3 or x1 >= x2 >= x3
|
|
* @param x2 - intermediate x value, where x1 <= x2 <= x3 or x1 >= x2 >= x3
|
|
* @param x3 - last x value, where x1 <= x2 <= x3 or x1 >= x2 >= x3
|
|
* @param y1 - first y value, where y1 <= y2 <= y3 or y1 >= y2 >= y3
|
|
* @param y3 - last y value, where y1 <= y2 <= y3 or y1 >= y2 >= y3
|
|
* @return y2 - an intermediate y value y1 <= y2 <= y3 or y1 >= y2 >= y3
|
|
* and the y value is linearly proportional to x1, x2, and x2.
|
|
*/
|
|
float linear_interpolate(float x1, float x2, float x3, float y1, float y3)
|
|
{
|
|
float y2;
|
|
|
|
if (y3 > y1) {
|
|
y2 = y1 + (((x2 - x1) * (y3 - y1)) / (x3 - x1));
|
|
} else {
|
|
y2 = y1 - (((x2 - x1) * (y1 - y3)) / (x3 - x1));
|
|
}
|
|
|
|
return y2;
|
|
}
|
|
|
|
/**
|
|
* Linearly Interpolate the values between y1 and y3 based on x
|
|
* and round up the result. Useful for integer interpolation.
|
|
*
|
|
* @param x1 - first x value, where x1 <= x2 <= x3 or x1 >= x2 >= x3
|
|
* @param x2 - intermediate x value, where x1 <= x2 <= x3 or x1 >= x2 >= x3
|
|
* @param x3 - last x value, where x1 <= x2 <= x3 or x1 >= x2 >= x3
|
|
* @param y1 - first y value, where y1 <= y2 <= y3 or y1 >= y2 >= y3
|
|
* @param y3 - last y value, where y1 <= y2 <= y3 or y1 >= y2 >= y3
|
|
* @return y2 - an intermediate y value y1 <= y2 <= y3 or y1 >= y2 >= y3
|
|
* and the y value is linearly proportional to x1, x2, and x2.
|
|
*/
|
|
float linear_interpolate_round(float x1, float x2, float x3, float y1, float y3)
|
|
{
|
|
float y2;
|
|
|
|
y2 = linear_interpolate(x1, x2, x3, y1, y3);
|
|
/* round away from zero */
|
|
if (y2 > 0.0f) {
|
|
y2 += 0.5f;
|
|
} else if (y2 < 0.0f) {
|
|
y2 -= 0.5f;
|
|
}
|
|
|
|
return y2;
|
|
}
|
|
|
|
/**
|
|
* Linearly Interpolate the values between y1 and y3 based on x
|
|
* using integer math.
|
|
*
|
|
* @param x1 - first x value, where x1 <= x2 <= x3 or x1 >= x2 >= x3
|
|
* @param x2 - intermediate x value, where x1 <= x2 <= x3 or x1 >= x2 >= x3
|
|
* @param x3 - last x value, where x1 <= x2 <= x3 or x1 >= x2 >= x3
|
|
* @param y1 - first y value, where y1 <= y2 <= y3 or y1 >= y2 >= y3
|
|
* @param y3 - last y value, where y1 <= y2 <= y3 or y1 >= y2 >= y3
|
|
* @return y2 - an intermediate y value y1 <= y2 <= y3 or y1 >= y2 >= y3
|
|
* and the y value is linearly proportional to x1, x2, and x2.
|
|
*/
|
|
long linear_interpolate_int(long x1, long x2, long x3, long y1, long y3)
|
|
{
|
|
long y2;
|
|
|
|
if (y3 > y1) {
|
|
y2 = y1 + (((x2 - x1) * (y3 - y1)) / (x3 - x1));
|
|
} else {
|
|
y2 = y1 - (((x2 - x1) * (y1 - y3)) / (x3 - x1));
|
|
}
|
|
|
|
return y2;
|
|
}
|