Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-07-22 06:57:04 +0300
committerCampbell Barton <campbell@blender.org>2022-07-22 06:59:36 +0300
commit087f27a52f7857887e90754d87a7a73715ebc3fb (patch)
tree94940ebc70e5668049f03735474dd6502514cc17 /source/blender/blenlib
parent08c5d99e88ee3e9f807dfe69c188660eae347f31 (diff)
Fix T87779: Asymmetric vertex positions in circles primitives
Add sin_cos_from_fraction which ensures each quadrant has matching values when their sign is flipped.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h20
-rw-r--r--source/blender/blenlib/intern/math_rotation.c49
2 files changed, 69 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index 192ad482a69..fef51fa780e 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -176,6 +176,26 @@ void mat3_to_quat_is_ok(float q[4], const float mat[3][3]);
/* Other. */
+/**
+ * Utility function that performs `sinf` & `cosf` where the quadrants of the circle
+ * will have exactly matching values when their sign is flipped.
+ * This works as long as the denominator can be divided by 2 or 4,
+ * otherwise `sinf` & `cosf` are used without any additional logic.
+ *
+ * Besides adjustments to precision, this function is the equivalent of:
+ * \code {.c}
+ * float phi = (2 * M_PI) * (float)i / (float)denominator;
+ * *r_sin = sinf(phi);
+ * *r_cos = cosf(phi);
+ * \endcode
+ *
+ * \param numerator: An integer factor in [0..denominator] (inclusive).
+ * \param denominator: The faction denominator (typically the number of segments of the circle).
+ * \param r_sin: The resulting sine.
+ * \param r_cos: The resulting cosine.
+ */
+void sin_cos_from_fraction(const int numerator, const int denominator, float *r_sin, float *r_cos);
+
void print_qt(const char *str, const float q[4]);
#define print_qt_id(q) print_qt(STRINGIFY(q), q)
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 92223bdf1d5..f0bfc7c21e1 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -915,6 +915,55 @@ float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[
return len;
}
+void sin_cos_from_fraction(const int numerator, const int denominator, float *r_sin, float *r_cos)
+{
+ BLI_assert((numerator <= denominator) && (denominator > 0));
+ if ((denominator & 3) == 0) {
+ const int denominator_4 = denominator / 4;
+ if (numerator <= denominator_4) {
+ /* Fall through. */
+ }
+ else {
+ if (numerator <= denominator_4 * 2) {
+ const float phi = (float)(2.0 * M_PI) *
+ ((float)(numerator - denominator_4) / (float)denominator);
+ *r_sin = cosf(phi);
+ *r_cos = -sinf(phi);
+ }
+ else if (numerator <= denominator_4 * 3) {
+ const float phi = (float)(2.0 * M_PI) *
+ ((float)(numerator - (denominator_4 * 2)) / (float)denominator);
+ *r_sin = -sinf(phi);
+ *r_cos = -cosf(phi);
+ }
+ else {
+ const float phi = (float)(2.0 * M_PI) *
+ ((float)(numerator - (denominator_4 * 3)) / (float)denominator);
+ *r_cos = sinf(phi);
+ *r_sin = -cosf(phi);
+ }
+ return;
+ }
+ }
+ else if ((denominator & 1) == 0) {
+ const int denominator_2 = denominator / 2;
+ if (numerator <= denominator_2) {
+ /* Fall through. */
+ }
+ else {
+ const float phi = (float)(2.0 * M_PI) *
+ ((float)(numerator - denominator_2) / (float)denominator);
+ *r_sin = -sinf(phi);
+ *r_cos = -cosf(phi);
+ return;
+ }
+ }
+
+ const float phi = (float)(2.0 * M_PI) * ((float)numerator / (float)denominator);
+ *r_sin = sinf(phi);
+ *r_cos = cosf(phi);
+}
+
void print_qt(const char *str, const float q[4])
{
printf("%s: %.3f %.3f %.3f %.3f\n", str, q[0], q[1], q[2], q[3]);