From f3adde8bbd7fbc930f5b3abd57a5481413ff5644 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 15 Dec 2023 18:40:19 +0100 Subject: [PATCH] REVIEWED: `DrawSplineLinear()` to `SUPPORT_SPLINE_MITERS` --- src/rshapes.c | 53 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/rshapes.c b/src/rshapes.c index b7fc0ed7..b8c17e70 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -1546,13 +1546,12 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl // Draw spline: linear, minimum 2 points void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) { - if (pointCount < 2) - { - return; - } - + if (pointCount < 2) return; + +#if defined(SUPPORT_SPLINE_MITERS) Vector2 prevNormal = (Vector2){-(points[1].y - points[0].y), (points[1].x - points[0].x)}; float prevLength = sqrtf(prevNormal.x*prevNormal.x + prevNormal.y*prevNormal.y); + if (prevLength > 0.0f) { prevNormal.x /= prevLength; @@ -1564,16 +1563,17 @@ void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) prevNormal.y = 0.0f; } - Vector2 prevRadius = {.5f * thick * prevNormal.x, .5f * thick * prevNormal.y}; + Vector2 prevRadius = { 0.5f*thick*prevNormal.x, 0.5f*thick*prevNormal.y }; for (int i = 0; i < pointCount - 1; i++) { - Vector2 normal = {0}; + Vector2 normal = { 0 }; if (i < pointCount - 2) { - normal = (Vector2){-(points[i+2].y - points[i+1].y), (points[i+2].x - points[i+1].x)}; + normal = (Vector2){-(points[i + 2].y - points[i + 1].y), (points[i + 2].x - points[i + 1].x)}; float normalLength = sqrtf(normal.x*normal.x + normal.y*normal.y); + if (normalLength > 0.0f) { normal.x /= normalLength; @@ -1590,8 +1590,9 @@ void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) normal = prevNormal; } - Vector2 radius = {prevNormal.x + normal.x, prevNormal.y + normal.y}; + Vector2 radius = { prevNormal.x + normal.x, prevNormal.y + normal.y }; float radiusLength = sqrtf(radius.x*radius.x + radius.y*radius.y); + if (radiusLength > 0.0f) { radius.x /= radiusLength; @@ -1603,12 +1604,12 @@ void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) radius.y = 0.0f; } - float cosTheta = radius.x * normal.x + radius.y * normal.y; + float cosTheta = radius.x*normal.x + radius.y*normal.y; if (cosTheta != 0.0f) { - radius.x *= thick * .5f / cosTheta; - radius.y *= thick * .5f / cosTheta; + radius.x *= (thick*0.5f/cosTheta); + radius.y *= (thick*0.5f/cosTheta); } else { @@ -1628,8 +1629,34 @@ void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) prevRadius = radius; prevNormal = normal; } -#if defined(SUPPORT_SPLINE_SEGMENT_CAPS) +#else // !SUPPORT_SPLINE_MITTERS + + Vector2 delta = { 0 }; + float length = 0.0f; + float scale = 0.0f; + + for (int i = 0; i < pointCount - 1; i++) + { + delta = (Vector2){ points[i + 1].x - points[i].x, points[i + 1].y - points[i].y }; + length = sqrtf(delta.x*delta.x + delta.y*delta.y); + + if (length > 0) scale = thick/(2*length); + + Vector2 radius = { -scale*delta.y, scale*delta.x }; + Vector2 strip[4] = { + { points[i].x - radius.x, points[i].y - radius.y }, + { points[i].x + radius.x, points[i].y + radius.y }, + { points[i + 1].x - radius.x, points[i + 1].y - radius.y }, + { points[i + 1].x + radius.x, points[i + 1].y + radius.y } + }; + + DrawTriangleStrip(strip, 4, color); + } +#endif + +#if defined(SUPPORT_SPLINE_SEGMENT_CAPS) + // TODO: Add spline segment rounded caps at the begin/end of the spline #endif }