tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_Bezier.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11#pragma once
12
13#include <cstddef>
14#include <cmath>
15
16namespace tracktion { inline namespace core
17{
18
19inline std::pair<double /*x*/, double /*y*/> getBezierPoint (double x1, double y1, double x2, double y2,
20 double c) noexcept
21{
22 if (y2 > y1)
23 {
24 auto run = x2 - x1;
25 auto rise = y2 - y1;
26
27 auto xc = x1 + run / 2;
28 auto yc = y1 + rise / 2;
29
30 auto x = xc - run / 2 * -c;
31 auto y = yc + rise / 2 * -c;
32
33 return { x, y };
34 }
35
36 auto run = x2 - x1;
37 auto rise = y1 - y2;
38
39 auto xc = x1 + run / 2;
40 auto yc = y2 + rise / 2;
41
42 auto x = xc - run / 2 * -c;
43 auto y = yc - rise / 2 * -c;
44
45 return { x, y };
46}
47
48inline void getBezierEnds (const double x1, const double y1, const double x2, const double y2, const double c,
49 double& x1out, double& y1out, double& x2out, double& y2out) noexcept
50{
51 auto minic = (std::abs (c) - 0.5f) * 2.0f;
52 auto run = minic * (x2 - x1);
53 auto rise = minic * ((y2 > y1) ? (y2 - y1) : (y1 - y2));
54
55 if (c > 0)
56 {
57 x1out = x1 + run;
58 y1out = (float) y1;
59
60 x2out = x2;
61 y2out = (float) (y1 < y2 ? (y2 - rise) : (y2 + rise));
62 }
63 else
64 {
65 x1out = x1;
66 y1out = (float) (y1 < y2 ? (y1 + rise) : (y1 - rise));
67
68 x2out = x2 - run;
69 y2out = (float) y2;
70 }
71}
72
73inline double getBezierYFromX (double x, double x1, double y1, double xb, double yb, double x2, double y2) noexcept
74{
75 // test for straight lines and bail out
76 if (x1 == x2 || y1 == y2)
77 return y1;
78
79 // test for endpoints
80 if (x <= x1) return y1;
81 if (x >= x2) return y2;
82
83 // ok, we have a bezier curve with one control point,
84 // we know x, we need to find y
85
86 // flip the bezier equation around so its an quadratic equation
87 auto a = x1 - 2 * xb + x2;
88 auto b = -2 * x1 + 2 * xb;
89 auto c = x1 - x;
90
91 // solve for t, [0..1]
92 double t;
93
94 if (a == 0)
95 {
96 t = -c / b;
97 }
98 else
99 {
100 t = (-b + std::sqrt (b * b - 4 * a * c)) / (2 * a);
101
102 if (t < 0.0f || t > 1.0f)
103 t = (-b - std::sqrt (b * b - 4 * a * c)) / (2 * a);
104 }
105
106 jassert (t >= 0.0f && t <= 1.0f);
107
108 // find y using the t we just found
109 auto y = (std::pow (1 - t, 2) * y1) + 2 * t * (1 - t) * yb + std::pow (t, 2) * y2;
110 return y;
111}
112
113}}
#define jassert(expression)
typedef float
T pow(T... args)
T sqrt(T... args)
y1