BLI_math: Add function to calculate circular cubic curve tangents
This commit is contained in:
@@ -470,6 +470,10 @@ MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2]);
|
||||
MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3]);
|
||||
MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[2]);
|
||||
|
||||
/********************************* Cubic (Bezier) *******************************/
|
||||
|
||||
float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3]);
|
||||
|
||||
/**************************** Inline Definitions ******************************/
|
||||
|
||||
#if BLI_MATH_DO_INLINE
|
||||
|
||||
@@ -4988,3 +4988,37 @@ int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], con
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value which the distance between points will need to be scaled by,
|
||||
* to define a handle, given both points are on a perfect circle.
|
||||
*
|
||||
* Use when we want a bezier curve to match a circle as closely as possible.
|
||||
*
|
||||
* \note the return value will need to be divided by 0.75 for correct results.
|
||||
*/
|
||||
float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
|
||||
{
|
||||
BLI_ASSERT_UNIT_V3(tan_l);
|
||||
BLI_ASSERT_UNIT_V3(tan_r);
|
||||
|
||||
const float eps = 1e-7f;
|
||||
const float tan_dot = dot_v3v3(tan_l, tan_r);
|
||||
if (tan_dot > 1.0f - eps) {
|
||||
/* no angle difference (use fallback, length wont make any difference) */
|
||||
return (1.0f / 3.0f) * 0.75f;
|
||||
}
|
||||
else if (tan_dot < -1.0f + eps) {
|
||||
/* parallele tangents (half-circle) */
|
||||
return (1.0f / 2.0f);
|
||||
}
|
||||
else {
|
||||
/* non-aligned tangents, calculate handle length */
|
||||
const float angle = acosf(tan_dot) / 2.0f;
|
||||
|
||||
/* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */
|
||||
const float angle_sin = sinf(angle);
|
||||
const float angle_cos = cosf(angle);
|
||||
return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user