REDESIGNED: Spline drawing functionality
This change allows more versatile and consistent splines drawing. It also gives more control to advance users to draw splines as individual segments.
This commit is contained in:
parent
bbf0c3a46d
commit
bd3ffa7db3
3 changed files with 206 additions and 46 deletions
|
@ -138,6 +138,10 @@
|
||||||
// Some lines-based shapes could still use lines
|
// Some lines-based shapes could still use lines
|
||||||
#define SUPPORT_QUADS_DRAW_MODE 1
|
#define SUPPORT_QUADS_DRAW_MODE 1
|
||||||
|
|
||||||
|
// rshapes: Configuration values
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
#define SPLINE_SEGMENT_DIVISIONS 24 // Spline segments subdivisions
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Module: rtextures - Configuration Flags
|
// Module: rtextures - Configuration Flags
|
||||||
|
|
21
src/raylib.h
21
src/raylib.h
|
@ -1256,18 +1256,23 @@ RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation
|
||||||
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
|
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
|
||||||
|
|
||||||
// Splines drawing functions
|
// Splines drawing functions
|
||||||
RLAPI void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: linear, minimum 2 points
|
RLAPI void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
|
||||||
RLAPI void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
|
RLAPI void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
|
||||||
RLAPI void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull Rom, minimum 4 points
|
RLAPI void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points
|
||||||
RLAPI void DrawSplineBezierQuad(Vector2 startPos, Vector2 controlPos, Vector2 endPos, float thick, Color color); // Draw spline segment: quadratic-bezier, one control point
|
RLAPI void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
|
||||||
RLAPI void DrawSplineBezierCubic(Vector2 startPos, Vector2 startControlPos, Vector2 endControlPos, Vector2 endPos, float thick, Color color); // Draw spline segment: cubic-bezier, two control points
|
RLAPI void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
|
||||||
|
RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points
|
||||||
|
RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points
|
||||||
|
RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points
|
||||||
|
RLAPI void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color); // Draw spline segment: Quadratic Bezier, 2 points, 1 control point
|
||||||
|
RLAPI void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color); // Draw spline segment: Cubic Bezier, 2 points, 2 control points
|
||||||
|
|
||||||
// Get (evaluate) spline point for a given t [0.0f .. 1.0f]
|
// Spline segment point evaluation functions, for a given t [0.0f .. 1.0f]
|
||||||
RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: linear
|
RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear
|
||||||
RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline
|
RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline
|
||||||
RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom
|
RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom
|
||||||
RLAPI Vector2 GetSplinePointBezierQuad(Vector2 startPos, Vector2 controlPos, Vector2 endPos, float t); // Get (evaluate) spline point: quadratic-bezier
|
RLAPI Vector2 GetSplinePointBezierQuad(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier
|
||||||
RLAPI Vector2 GetSplinePointBezierCubic(Vector2 startPos, Vector2 startControlPos, Vector2 endControlPos, Vector2 endPos, float t); // Get (evaluate) spline point: cubic-bezier
|
RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t); // Get (evaluate) spline point: Cubic Bezier
|
||||||
|
|
||||||
// Basic shapes collision detection functions
|
// Basic shapes collision detection functions
|
||||||
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
|
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
|
||||||
|
|
227
src/rshapes.c
227
src/rshapes.c
|
@ -65,10 +65,10 @@
|
||||||
// Error rate to calculate how many segments we need to draw a smooth circle,
|
// Error rate to calculate how many segments we need to draw a smooth circle,
|
||||||
// taken from https://stackoverflow.com/a/2244088
|
// taken from https://stackoverflow.com/a/2244088
|
||||||
#ifndef SMOOTH_CIRCLE_ERROR_RATE
|
#ifndef SMOOTH_CIRCLE_ERROR_RATE
|
||||||
#define SMOOTH_CIRCLE_ERROR_RATE 0.5f // Circle error rate
|
#define SMOOTH_CIRCLE_ERROR_RATE 0.5f // Circle error rate
|
||||||
#endif
|
#endif
|
||||||
#ifndef SPLINE_LINE_DIVISIONS
|
#ifndef SPLINE_SEGMENT_DIVISIONS
|
||||||
#define SPLINE_LINE_DIVISIONS 24 // Spline lines segment divisions
|
#define SPLINE_SEGMENT_DIVISIONS 24 // Spline segment divisions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,14 +204,14 @@ void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color)
|
||||||
Vector2 previous = startPos;
|
Vector2 previous = startPos;
|
||||||
Vector2 current = { 0 };
|
Vector2 current = { 0 };
|
||||||
|
|
||||||
Vector2 points[2*SPLINE_LINE_DIVISIONS + 2] = { 0 };
|
Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 };
|
||||||
|
|
||||||
for (int i = 1; i <= SPLINE_LINE_DIVISIONS; i++)
|
for (int i = 1; i <= SPLINE_SEGMENT_DIVISIONS; i++)
|
||||||
{
|
{
|
||||||
// Cubic easing in-out
|
// Cubic easing in-out
|
||||||
// NOTE: Easing is calculated only for y position value
|
// NOTE: Easing is calculated only for y position value
|
||||||
current.y = EaseCubicInOut((float)i, startPos.y, endPos.y - startPos.y, (float)SPLINE_LINE_DIVISIONS);
|
current.y = EaseCubicInOut((float)i, startPos.y, endPos.y - startPos.y, (float)SPLINE_SEGMENT_DIVISIONS);
|
||||||
current.x = previous.x + (endPos.x - startPos.x)/(float)SPLINE_LINE_DIVISIONS;
|
current.x = previous.x + (endPos.x - startPos.x)/(float)SPLINE_SEGMENT_DIVISIONS;
|
||||||
|
|
||||||
float dy = current.y - previous.y;
|
float dy = current.y - previous.y;
|
||||||
float dx = current.x - previous.x;
|
float dx = current.x - previous.x;
|
||||||
|
@ -233,7 +233,7 @@ void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color)
|
||||||
previous = current;
|
previous = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawTriangleStrip(points, 2*SPLINE_LINE_DIVISIONS + 2, color);
|
DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a line defining thickness
|
// Draw a line defining thickness
|
||||||
|
@ -1567,6 +1567,9 @@ void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color)
|
||||||
|
|
||||||
DrawTriangleStrip(strip, 4, color);
|
DrawTriangleStrip(strip, 4, color);
|
||||||
}
|
}
|
||||||
|
#if defined(SUPPORT_SPLINE_SEGMENT_CAPS)
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw spline: B-Spline, minimum 4 points
|
// Draw spline: B-Spline, minimum 4 points
|
||||||
|
@ -1582,7 +1585,7 @@ void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color)
|
||||||
|
|
||||||
Vector2 currentPoint = { 0 };
|
Vector2 currentPoint = { 0 };
|
||||||
Vector2 nextPoint = { 0 };
|
Vector2 nextPoint = { 0 };
|
||||||
Vector2 vertices[2*SPLINE_LINE_DIVISIONS + 2] = { 0 };
|
Vector2 vertices[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 };
|
||||||
|
|
||||||
for (int i = 0; i < (pointCount - 3); i++)
|
for (int i = 0; i < (pointCount - 3); i++)
|
||||||
{
|
{
|
||||||
|
@ -1612,9 +1615,9 @@ void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color)
|
||||||
vertices[1].y = currentPoint.y + dx*size;
|
vertices[1].y = currentPoint.y + dx*size;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 1; j <= SPLINE_LINE_DIVISIONS; j++)
|
for (int j = 1; j <= SPLINE_SEGMENT_DIVISIONS; j++)
|
||||||
{
|
{
|
||||||
t = ((float)j)/((float)SPLINE_LINE_DIVISIONS);
|
t = ((float)j)/((float)SPLINE_SEGMENT_DIVISIONS);
|
||||||
|
|
||||||
nextPoint.x = a[3] + t*(a[2] + t*(a[1] + t*a[0]));
|
nextPoint.x = a[3] + t*(a[2] + t*(a[1] + t*a[0]));
|
||||||
nextPoint.y = b[3] + t*(b[2] + t*(b[1] + t*b[0]));
|
nextPoint.y = b[3] + t*(b[2] + t*(b[1] + t*b[0]));
|
||||||
|
@ -1639,13 +1642,13 @@ void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color)
|
||||||
currentPoint = nextPoint;
|
currentPoint = nextPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawTriangleStrip(vertices, 2*SPLINE_LINE_DIVISIONS + 2, color);
|
DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap
|
DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw spline: Catmull Rom, minimum 4 points
|
// Draw spline: Catmull-Rom, minimum 4 points
|
||||||
void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color)
|
void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color)
|
||||||
{
|
{
|
||||||
if (pointCount < 4) return;
|
if (pointCount < 4) return;
|
||||||
|
@ -1656,7 +1659,7 @@ void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color co
|
||||||
|
|
||||||
Vector2 currentPoint = points[1];
|
Vector2 currentPoint = points[1];
|
||||||
Vector2 nextPoint = { 0 };
|
Vector2 nextPoint = { 0 };
|
||||||
Vector2 vertices[2*SPLINE_LINE_DIVISIONS + 2] = { 0 };
|
Vector2 vertices[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 };
|
||||||
|
|
||||||
DrawCircleV(currentPoint, thick/2.0f, color); // Draw init line circle-cap
|
DrawCircleV(currentPoint, thick/2.0f, color); // Draw init line circle-cap
|
||||||
|
|
||||||
|
@ -1673,9 +1676,9 @@ void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color co
|
||||||
vertices[1].y = currentPoint.y + dx*size;
|
vertices[1].y = currentPoint.y + dx*size;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 1; j <= SPLINE_LINE_DIVISIONS; j++)
|
for (int j = 1; j <= SPLINE_SEGMENT_DIVISIONS; j++)
|
||||||
{
|
{
|
||||||
t = ((float)j)/((float)SPLINE_LINE_DIVISIONS);
|
t = ((float)j)/((float)SPLINE_SEGMENT_DIVISIONS);
|
||||||
|
|
||||||
float q0 = (-1.0f*t*t*t) + (2.0f*t*t) + (-1.0f*t);
|
float q0 = (-1.0f*t*t*t) + (2.0f*t*t) + (-1.0f*t);
|
||||||
float q1 = (3.0f*t*t*t) + (-5.0f*t*t) + 2.0f;
|
float q1 = (3.0f*t*t*t) + (-5.0f*t*t) + 2.0f;
|
||||||
|
@ -1705,35 +1708,183 @@ void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color co
|
||||||
currentPoint = nextPoint;
|
currentPoint = nextPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawTriangleStrip(vertices, 2*SPLINE_LINE_DIVISIONS + 2, color);
|
DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap
|
DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
|
||||||
// Draw spline segment: quadratic-bezier, one control point
|
void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color)
|
||||||
void DrawSplineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color)
|
|
||||||
{
|
{
|
||||||
const float step = 1.0f/SPLINE_LINE_DIVISIONS;
|
if (pointCount < 3) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < pointCount - 2; i++)
|
||||||
|
{
|
||||||
|
DrawSplineSegmentBezierQuadratic(points[i], points[i + 1], points[i + 2], thick, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 previous = startPos;
|
// Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
|
||||||
|
void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color)
|
||||||
|
{
|
||||||
|
if (pointCount < 4) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < pointCount - 3; i++)
|
||||||
|
{
|
||||||
|
DrawSplineSegmentBezierCubic(points[i], points[i + 1], points[i + 2], points[i + 3], thick, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw spline segment: Linear, 2 points
|
||||||
|
void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color)
|
||||||
|
{
|
||||||
|
// NOTE: For the linear spline we don't use subdivisions, just a single quad
|
||||||
|
|
||||||
|
Vector2 delta = { p2.x - p1.x, p2.y - p1.y };
|
||||||
|
float length = sqrtf(delta.x*delta.x + delta.y*delta.y);
|
||||||
|
|
||||||
|
if ((length > 0) && (thick > 0))
|
||||||
|
{
|
||||||
|
float scale = thick/(2*length);
|
||||||
|
|
||||||
|
Vector2 radius = { -scale*delta.y, scale*delta.x };
|
||||||
|
Vector2 strip[4] = {
|
||||||
|
{ p1.x - radius.x, p1.y - radius.y },
|
||||||
|
{ p1.x + radius.x, p1.y + radius.y },
|
||||||
|
{ p2.x - radius.x, p2.y - radius.y },
|
||||||
|
{ p2.x + radius.x, p2.y + radius.y }
|
||||||
|
};
|
||||||
|
|
||||||
|
DrawTriangleStrip(strip, 4, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw spline segment: B-Spline, 4 points
|
||||||
|
void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color)
|
||||||
|
{
|
||||||
|
const float step = 1.0f/SPLINE_SEGMENT_DIVISIONS;
|
||||||
|
|
||||||
|
Vector2 currentPoint = { 0 };
|
||||||
|
Vector2 nextPoint = { 0 };
|
||||||
|
float t = 0.0f;
|
||||||
|
|
||||||
|
Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 };
|
||||||
|
|
||||||
|
float a[4] = { 0 };
|
||||||
|
float b[4] = { 0 };
|
||||||
|
|
||||||
|
a[0] = (-p1.x + 3*p2.x - 3*p3.x + p4.x)/6.0f;
|
||||||
|
a[1] = (3*p1.x - 6*p2.x + 3*p3.x)/6.0f;
|
||||||
|
a[2] = (-3*p1.x + 3*p3.x)/6.0f;
|
||||||
|
a[3] = (p1.x + 4*p2.x + p3.x)/6.0f;
|
||||||
|
|
||||||
|
b[0] = (-p1.y + 3*p2.y - 3*p3.y + p4.y)/6.0f;
|
||||||
|
b[1] = (3*p1.y - 6*p2.y + 3*p3.y)/6.0f;
|
||||||
|
b[2] = (-3*p1.y + 3*p3.y)/6.0f;
|
||||||
|
b[3] = (p1.y + 4*p2.y + p3.y)/6.0f;
|
||||||
|
|
||||||
|
currentPoint.x = a[3];
|
||||||
|
currentPoint.y = b[3];
|
||||||
|
|
||||||
|
for (int i = 0; i <= SPLINE_SEGMENT_DIVISIONS; i++)
|
||||||
|
{
|
||||||
|
t = step*(float)i;
|
||||||
|
|
||||||
|
nextPoint.x = a[3] + t*(a[2] + t*(a[1] + t*a[0]));
|
||||||
|
nextPoint.y = b[3] + t*(b[2] + t*(b[1] + t*b[0]));
|
||||||
|
|
||||||
|
float dy = nextPoint.y - currentPoint.y;
|
||||||
|
float dx = nextPoint.x - currentPoint.x;
|
||||||
|
float size = (0.5f*thick)/sqrtf(dx*dx + dy*dy);
|
||||||
|
|
||||||
|
if (i == 1)
|
||||||
|
{
|
||||||
|
points[0].x = currentPoint.x + dy*size;
|
||||||
|
points[0].y = currentPoint.y - dx*size;
|
||||||
|
points[1].x = currentPoint.x - dy*size;
|
||||||
|
points[1].y = currentPoint.y + dx*size;
|
||||||
|
}
|
||||||
|
|
||||||
|
points[2*i + 1].x = nextPoint.x - dy*size;
|
||||||
|
points[2*i + 1].y = nextPoint.y + dx*size;
|
||||||
|
points[2*i].x = nextPoint.x + dy*size;
|
||||||
|
points[2*i].y = nextPoint.y - dx*size;
|
||||||
|
|
||||||
|
currentPoint = nextPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS+2, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw spline segment: Catmull-Rom, 4 points
|
||||||
|
void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color)
|
||||||
|
{
|
||||||
|
const float step = 1.0f/SPLINE_SEGMENT_DIVISIONS;
|
||||||
|
|
||||||
|
Vector2 currentPoint = p1;
|
||||||
|
Vector2 nextPoint = { 0 };
|
||||||
|
float t = 0.0f;
|
||||||
|
|
||||||
|
Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 };
|
||||||
|
|
||||||
|
for (int i = 0; i <= SPLINE_SEGMENT_DIVISIONS; i++)
|
||||||
|
{
|
||||||
|
t = step*(float)i;
|
||||||
|
|
||||||
|
float q0 = (-1*t*t*t) + (2*t*t) + (-1*t);
|
||||||
|
float q1 = (3*t*t*t) + (-5*t*t) + 2;
|
||||||
|
float q2 = (-3*t*t*t) + (4*t*t) + t;
|
||||||
|
float q3 = t*t*t - t*t;
|
||||||
|
|
||||||
|
nextPoint.x = 0.5f*((p1.x*q0) + (p2.x*q1) + (p3.x*q2) + (p4.x*q3));
|
||||||
|
nextPoint.y = 0.5f*((p1.y*q0) + (p2.y*q1) + (p3.y*q2) + (p4.y*q3));
|
||||||
|
|
||||||
|
float dy = nextPoint.y - currentPoint.y;
|
||||||
|
float dx = nextPoint.x - currentPoint.x;
|
||||||
|
float size = (0.5f*thick)/sqrtf(dx*dx + dy*dy);
|
||||||
|
|
||||||
|
if (i == 1)
|
||||||
|
{
|
||||||
|
points[0].x = currentPoint.x + dy*size;
|
||||||
|
points[0].y = currentPoint.y - dx*size;
|
||||||
|
points[1].x = currentPoint.x - dy*size;
|
||||||
|
points[1].y = currentPoint.y + dx*size;
|
||||||
|
}
|
||||||
|
|
||||||
|
points[2*i + 1].x = nextPoint.x - dy*size;
|
||||||
|
points[2*i + 1].y = nextPoint.y + dx*size;
|
||||||
|
points[2*i].x = nextPoint.x + dy*size;
|
||||||
|
points[2*i].y = nextPoint.y - dx*size;
|
||||||
|
|
||||||
|
currentPoint = nextPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw spline segment: Quadratic Bezier, 2 points, 1 control point
|
||||||
|
void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color)
|
||||||
|
{
|
||||||
|
const float step = 1.0f/SPLINE_SEGMENT_DIVISIONS;
|
||||||
|
|
||||||
|
Vector2 previous = p1;
|
||||||
Vector2 current = { 0 };
|
Vector2 current = { 0 };
|
||||||
float t = 0.0f;
|
float t = 0.0f;
|
||||||
|
|
||||||
Vector2 points[2*SPLINE_LINE_DIVISIONS + 2] = { 0 };
|
Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 };
|
||||||
|
|
||||||
for (int i = 1; i <= SPLINE_LINE_DIVISIONS; i++)
|
for (int i = 1; i <= SPLINE_SEGMENT_DIVISIONS; i++)
|
||||||
{
|
{
|
||||||
t = step*i;
|
t = step*(float)i;
|
||||||
|
|
||||||
float a = powf(1.0f - t, 2);
|
float a = powf(1.0f - t, 2);
|
||||||
float b = 2.0f*(1.0f - t)*t;
|
float b = 2.0f*(1.0f - t)*t;
|
||||||
float c = powf(t, 2);
|
float c = powf(t, 2);
|
||||||
|
|
||||||
// NOTE: The easing functions aren't suitable here because they don't take a control point
|
// NOTE: The easing functions aren't suitable here because they don't take a control point
|
||||||
current.y = a*startPos.y + b*controlPos.y + c*endPos.y;
|
current.y = a*p1.y + b*c2.y + c*p3.y;
|
||||||
current.x = a*startPos.x + b*controlPos.x + c*endPos.x;
|
current.x = a*p1.x + b*c2.x + c*p3.x;
|
||||||
|
|
||||||
float dy = current.y - previous.y;
|
float dy = current.y - previous.y;
|
||||||
float dx = current.x - previous.x;
|
float dx = current.x - previous.x;
|
||||||
|
@ -1755,31 +1906,31 @@ void DrawSplineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos,
|
||||||
previous = current;
|
previous = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawTriangleStrip(points, 2*SPLINE_LINE_DIVISIONS + 2, color);
|
DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw spline segment: cubic-bezier, two control point
|
// Draw spline segment: Cubic Bezier, 2 points, 2 control points
|
||||||
void DrawSplineBezierCubic(Vector2 startPos, Vector2 startControlPos, Vector2 endControlPos, Vector2 endPos, float thick, Color color)
|
void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color)
|
||||||
{
|
{
|
||||||
const float step = 1.0f/SPLINE_LINE_DIVISIONS;
|
const float step = 1.0f/SPLINE_SEGMENT_DIVISIONS;
|
||||||
|
|
||||||
Vector2 previous = startPos;
|
Vector2 previous = p1;
|
||||||
Vector2 current = { 0 };
|
Vector2 current = { 0 };
|
||||||
float t = 0.0f;
|
float t = 0.0f;
|
||||||
|
|
||||||
Vector2 points[2*SPLINE_LINE_DIVISIONS + 2] = { 0 };
|
Vector2 points[2*SPLINE_SEGMENT_DIVISIONS + 2] = { 0 };
|
||||||
|
|
||||||
for (int i = 1; i <= SPLINE_LINE_DIVISIONS; i++)
|
for (int i = 1; i <= SPLINE_SEGMENT_DIVISIONS; i++)
|
||||||
{
|
{
|
||||||
t = step*i;
|
t = step*(float)i;
|
||||||
|
|
||||||
float a = powf(1.0f - t, 3);
|
float a = powf(1.0f - t, 3);
|
||||||
float b = 3.0f*powf(1.0f - t, 2)*t;
|
float b = 3.0f*powf(1.0f - t, 2)*t;
|
||||||
float c = 3.0f*(1.0f - t)*powf(t, 2);
|
float c = 3.0f*(1.0f - t)*powf(t, 2);
|
||||||
float d = powf(t, 3);
|
float d = powf(t, 3);
|
||||||
|
|
||||||
current.y = a*startPos.y + b*startControlPos.y + c*endControlPos.y + d*endPos.y;
|
current.y = a*p1.y + b*c2.y + c*c3.y + d*p4.y;
|
||||||
current.x = a*startPos.x + b*startControlPos.x + c*endControlPos.x + d*endPos.x;
|
current.x = a*p1.x + b*c2.x + c*c3.x + d*p4.x;
|
||||||
|
|
||||||
float dy = current.y - previous.y;
|
float dy = current.y - previous.y;
|
||||||
float dx = current.x - previous.x;
|
float dx = current.x - previous.x;
|
||||||
|
@ -1801,7 +1952,7 @@ void DrawSplineBezierCubic(Vector2 startPos, Vector2 startControlPos, Vector2 en
|
||||||
previous = current;
|
previous = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawTriangleStrip(points, 2*SPLINE_LINE_DIVISIONS + 2, color);
|
DrawTriangleStrip(points, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get spline point for a given t [0.0f .. 1.0f], Linear
|
// Get spline point for a given t [0.0f .. 1.0f], Linear
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue