mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-26 16:16:46 +00:00
common bezier: Add a function that returns the position.
A utility for common use of the Bezier curve.
This commit is contained in:
parent
81afba5035
commit
def6393d82
2 changed files with 28 additions and 10 deletions
|
@ -20,8 +20,7 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <float.h>
|
#include "tvgMath.h"
|
||||||
#include <math.h>
|
|
||||||
#include "tvgBezier.h"
|
#include "tvgBezier.h"
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
@ -75,7 +74,7 @@ float bezLength(const Bezier& cur)
|
||||||
auto len = _lineLength(cur.start, cur.ctrl1) + _lineLength(cur.ctrl1, cur.ctrl2) + _lineLength(cur.ctrl2, cur.end);
|
auto len = _lineLength(cur.start, cur.ctrl1) + _lineLength(cur.ctrl1, cur.ctrl2) + _lineLength(cur.ctrl2, cur.end);
|
||||||
auto chord = _lineLength(cur.start, cur.end);
|
auto chord = _lineLength(cur.start, cur.end);
|
||||||
|
|
||||||
if (fabsf(len - chord) > BEZIER_EPSILON) {
|
if (!mathEqual(len, chord)) {
|
||||||
bezSplit(cur, left, right);
|
bezSplit(cur, left, right);
|
||||||
return bezLength(left) + bezLength(right);
|
return bezLength(left) + bezLength(right);
|
||||||
}
|
}
|
||||||
|
@ -116,19 +115,16 @@ float bezAt(const Bezier& bz, float at)
|
||||||
|
|
||||||
//just in case to prevent an infinite loop
|
//just in case to prevent an infinite loop
|
||||||
if (at <= 0) return 0.0f;
|
if (at <= 0) return 0.0f;
|
||||||
|
if (at >= len) return len;
|
||||||
if (at >= len) return 1.0f;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto right = bz;
|
auto right = bz;
|
||||||
Bezier left;
|
Bezier left;
|
||||||
bezSplitLeft(right, t, left);
|
bezSplitLeft(right, t, left);
|
||||||
len = bezLength(left);
|
len = bezLength(left);
|
||||||
|
if (mathEqual(len, at) || mathEqual(smallest, biggest)) {
|
||||||
if (fabsf(len - at) < BEZIER_EPSILON || fabsf(smallest - biggest) < BEZIER_EPSILON) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len < at) {
|
if (len < at) {
|
||||||
smallest = t;
|
smallest = t;
|
||||||
t = (t + biggest) * 0.5f;
|
t = (t + biggest) * 0.5f;
|
||||||
|
@ -148,4 +144,27 @@ void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right)
|
||||||
bezSplitLeft(right, t, left);
|
bezSplitLeft(right, t, left);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Point bezPointAt(const Bezier& bz, float t)
|
||||||
|
{
|
||||||
|
Point cur;
|
||||||
|
auto it = 1.0f - t;
|
||||||
|
|
||||||
|
auto ax = bz.start.x * it + bz.ctrl1.x * t;
|
||||||
|
auto bx = bz.ctrl1.x * it + bz.ctrl2.x * t;
|
||||||
|
auto cx = bz.ctrl2.x * it + bz.end.x * t;
|
||||||
|
ax = ax * it + bx * t;
|
||||||
|
bx = bx * it + cx * t;
|
||||||
|
cur.x = ax * it + bx * t;
|
||||||
|
|
||||||
|
float ay = bz.start.y * it + bz.ctrl1.y * t;
|
||||||
|
float by = bz.ctrl1.y * it + bz.ctrl2.y * t;
|
||||||
|
float cy = bz.ctrl2.y * it + bz.end.y * t;
|
||||||
|
ay = ay * it + by * t;
|
||||||
|
by = by * it + cy * t;
|
||||||
|
cur.y = ay * it + by * t;
|
||||||
|
|
||||||
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,8 +28,6 @@
|
||||||
namespace tvg
|
namespace tvg
|
||||||
{
|
{
|
||||||
|
|
||||||
#define BEZIER_EPSILON 1e-4f
|
|
||||||
|
|
||||||
struct Bezier
|
struct Bezier
|
||||||
{
|
{
|
||||||
Point start;
|
Point start;
|
||||||
|
@ -43,6 +41,7 @@ float bezLength(const Bezier& cur);
|
||||||
void bezSplitLeft(Bezier& cur, float at, Bezier& left);
|
void bezSplitLeft(Bezier& cur, float at, Bezier& left);
|
||||||
float bezAt(const Bezier& bz, float at);
|
float bezAt(const Bezier& bz, float at);
|
||||||
void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right);
|
void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right);
|
||||||
|
Point bezPointAt(const Bezier& bz, float t);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue