This commit is contained in:
Ray 2026-08-04 21:16:17 +02:00
commit 3d671a6dd4

View file

@ -637,24 +637,53 @@ void DrawRectangleLinesEx(Rectangle rec, float thick, Color color)
else if (rec.width <= rec.height) thick = rec.width/2; else if (rec.width <= rec.height) thick = rec.width/2;
} }
// When rec = { x, y, 8.0f, 6.0f } and thick = 2, the following
// four rectangles are drawn ([T]op, [B]ottom, [L]eft, [R]ight):
//
// TTTTTTTT
// TTTTTTTT
// LL RR
// LL RR
// BBBBBBBB
// BBBBBBBB
//
if (thick > 0.0f) if (thick > 0.0f)
{ {
// When rec = { x, y, 8.0f, 6.0f } and thick = 2, the following
// four rectangles are drawn ([T]op, [B]ottom, [L]eft, [R]ight):
//
// TTTTTTTT
// TTTTTTTT
// LL RR
// LL RR
// BBBBBBBB
// BBBBBBBB
//
Rectangle top = { rec.x, rec.y, rec.width, thick }; Rectangle top = { rec.x, rec.y, rec.width, thick };
Rectangle bottom = { rec.x, rec.y - thick + rec.height, rec.width, thick }; Rectangle bottom = { rec.x, rec.y - thick + rec.height, rec.width, thick };
Rectangle left = { rec.x, rec.y + thick, thick, rec.height - thick*2.0f }; Rectangle left = { rec.x, rec.y + thick, thick, rec.height - thick*2.0f };
Rectangle right = { rec.x - thick + rec.width, rec.y + thick, thick, rec.height - thick*2.0f }; Rectangle right = { rec.x - thick + rec.width, rec.y + thick, thick, rec.height - thick*2.0f };
DrawRectangleRec(top, color);
DrawRectangleRec(bottom, color);
DrawRectangleRec(left, color);
DrawRectangleRec(right, color);
}
else
{
// When rec = { x, y, 8.0f, 6.0f } and thick = -2, the following
// four rectangles are drawn ([T]op, [B]ottom, [L]eft, [R]ight):
//
// TTTTTTTTTTTT
// TTTTTTTTTTTT
// LL RR
// LL RR
// LL RR
// LL RR
// LL RR
// LL RR
// BBBBBBBBBBBB
// BBBBBBBBBBBB
//
thick *= -1.0f;
Rectangle top = { rec.x - thick, rec.y - thick, rec.width + thick*2.0f, thick };
Rectangle bottom = { rec.x - thick, rec.y + rec.height, rec.width + thick*2.0f, thick};
Rectangle left = { rec.x - thick, rec.y, thick, rec.height };
Rectangle right = { rec.x + rec.width, rec.y, thick, rec.height };
DrawRectangleRec(top, color); DrawRectangleRec(top, color);
DrawRectangleRec(bottom, color); DrawRectangleRec(bottom, color);
DrawRectangleRec(left, color); DrawRectangleRec(left, color);
@ -931,22 +960,35 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Col
\ / \ /
P5 ------------------ P4 P5 ------------------ P4
*/ */
// The x-coordinates used for the outline
const float x0 = rec.x + radius + 0.5f;
const float x1 = (rec.x + rec.width) - radius - 0.5f;
const float x2 = rec.x + rec.width - 0.5f;
const float x3 = rec.x + 0.5f;
// The y-coordinates used for the outline
const float y0 = rec.y + 0.5f;
const float y1 = rec.y + radius + 0.5f;
const float y2 = (rec.y + rec.height) - radius - 0.5f;
const float y3 = rec.y + rec.height - 0.5f;
const Vector2 point[8] = { const Vector2 point[8] = {
{(float)rec.x + radius + 0.5f, rec.y + 0.5f}, {x0, y0}, // P0
{(float)(rec.x + rec.width) - radius - 0.5f, rec.y + 0.5f}, {x1, y0}, // P1
{rec.x + rec.width - 0.5f, (float)rec.y + radius + 0.5f}, // PO, P1, P2 {x2, y1}, // P2
{rec.x + rec.width - 0.5f, (float)(rec.y + rec.height) - radius - 0.5f}, {x2, y2}, // P3
{(float)(rec.x + rec.width) - radius - 0.5f, rec.y + rec.height - 0.5f}, // P3, P4 {x1, y3}, // P4
{(float)rec.x + radius + 0.5f, rec.y + rec.height - 0.5f}, {x0, y3}, // P5
{rec.x + 0.5f, (float)(rec.y + rec.height) - radius - 0.5f}, {x3, y2}, // P6
{rec.x + 0.5f, (float)rec.y + radius + 0.5f}, // P5, P6, P7 {x3, y1}, // P7
}; };
const Vector2 centers[4] = { const Vector2 centers[4] = {
{(float)rec.x + radius + 0.5f, (float)rec.y + radius + 0.5f}, {x0, y1}, // P16
{(float)(rec.x + rec.width) - radius - 0.5f, (float)rec.y + radius + 0.5f}, // P16, P17 {x1, y1}, // P17
{(float)(rec.x + rec.width) - radius - 0.5f, (float)(rec.y + rec.height) - radius - 0.5f}, {x1, y2}, // P18
{(float)rec.x + radius + 0.5f, (float)(rec.y + rec.height) - radius - 0.5f} // P18, P19 {x0, y2} // P19
}; };
const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f }; const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f };
@ -980,32 +1022,81 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Col
// Draw rectangle with rounded edges outline with line thickness // Draw rectangle with rounded edges outline with line thickness
void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float thick, Color color) void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float thick, Color color)
{ {
if (thick <= 0) return;
// Not a rounded rectangle // Not a rounded rectangle
if (roundness <= 0.0f) if (roundness <= 0.0f)
{ {
DrawRectangleLinesEx((Rectangle){rec.x - thick, rec.y - thick, rec.width + 2*thick, rec.height + 2*thick}, thick, color); DrawRectangleLinesEx(rec, thick, color);
return; return;
} }
if (roundness >= 1.0f) roundness = 1.0f; if (roundness >= 1.0f) roundness = 1.0f;
// Calculate corner radius float radius = 0.0f;
float radius = (rec.width > rec.height)? (rec.height*roundness)/2 : (rec.width*roundness)/2; float roundedOutlineThick = 0.0f;
if (radius <= 0.0f) return; float outerRadius = 0.0f;
float innerRadius = 0.0f;
// Calculate number of segments to use for the corners if (thick >= 0.0f)
if (segments < 4)
{ {
// Calculate the maximum angle between segments based on the error rate (usually 0.5f) // Calculate corner radius
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1); radius = (rec.width > rec.height)? (rec.height*roundness)/2 : (rec.width*roundness)/2;
segments = (int)ceilf((2*PI/th)/4.0f); if (radius <= 0.0f) return;
if (segments <= 0) segments = 4;
outerRadius = radius;
innerRadius = outerRadius - thick;
// The maximum thickness the outline can have and still be rounded on the interior edge is equal to the corner radius
// Put another way, when `innerRadius <= 0`, the interior of the outline is just a normal rectangle with no rounding
if (innerRadius <= 0.0f)
{
innerRadius = 0.0f;
roundedOutlineThick = outerRadius;
// Draw the not-rounded portion of the outline
DrawRectangleLinesEx((Rectangle){ rec.x + outerRadius, rec.y + outerRadius, rec.width - outerRadius*2.0f, rec.height - outerRadius*2.0f }, thick - outerRadius, color);
}
else
{
roundedOutlineThick = thick;
}
// Calculate number of segments to use for the corners
if (segments < 4)
{
// Calculate the maximum angle between segments based on the error rate (usually 0.5f)
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/outerRadius, 2) - 1);
segments = (int)ceilf((2*PI/th)/4.0f);
if (segments <= 0) segments = 4;
}
}
else
{
thick *= -1.0f;
// Calculate corner radius
radius = (rec.width > rec.height)? (rec.height*roundness)/2 : (rec.width*roundness)/2;
if (radius <= 0.0f) return; // Only possible if the rectangle has 0 width or height
// Expand the rectangle
rec.x -= thick;
rec.y -= thick;
rec.width += thick*2.0f;
rec.height += thick*2.0f;
innerRadius = radius;
outerRadius = innerRadius + thick;
roundedOutlineThick = thick;
// Calculate number of segments to use for the corners
if (segments < 4)
{
// Calculate the maximum angle between segments based on the error rate (usually 0.5f)
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/innerRadius, 2) - 1);
segments = (int)ceilf((2*PI/th)/4.0f);
if (segments <= 0) segments = 4;
}
} }
float stepLength = 90.0f/(float)segments; float stepLength = 90.0f/(float)segments;
const float outerRadius = radius + thick, innerRadius = radius;
/* /*
Quick sketch to make sense of all of this, Quick sketch to make sense of all of this,
@ -1023,30 +1114,47 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f
\\ P13 P12 // \\ P13 P12 //
P5 ================== P4 P5 ================== P4
*/ */
// The x-coordinates used for the outline
const float x0 = rec.x + outerRadius;
const float x1 = (rec.x + rec.width) - outerRadius;
const float x2 = rec.x + rec.width;
const float x3 = rec.x;
const float x4 = rec.x + rec.width - roundedOutlineThick;
const float x5 = rec.x + roundedOutlineThick;
// The y-coordinates used for the outline
const float y0 = rec.y;
const float y1 = rec.y + outerRadius;
const float y2 = (rec.y + rec.height) - outerRadius;
const float y3 = rec.y + rec.height;
const float y4 = rec.y + roundedOutlineThick;
const float y5 = rec.y + rec.height - roundedOutlineThick;
const Vector2 point[16] = { const Vector2 point[16] = {
{(float)rec.x + innerRadius + 0.5f, rec.y - thick + 0.5f}, {x0, y0}, // P0
{(float)(rec.x + rec.width) - innerRadius - 0.5f, rec.y - thick + 0.5f}, {x1, y0}, // P1
{rec.x + rec.width + thick - 0.5f, (float)rec.y + innerRadius + 0.5f}, // PO, P1, P2 {x2, y1}, // P2
{rec.x + rec.width + thick - 0.5f, (float)(rec.y + rec.height) - innerRadius - 0.5f}, {x2, y2}, // P3
{(float)(rec.x + rec.width) - innerRadius - 0.5f, rec.y + rec.height + thick - 0.5f}, // P3, P4 {x1, y3}, // P4
{(float)rec.x + innerRadius + 0.5f, rec.y + rec.height + thick - 0.5f}, {x0, y3}, // P5
{rec.x - thick + 0.5f, (float)(rec.y + rec.height) - innerRadius - 0.5f}, {x3, y2}, // P6
{rec.x - thick + 0.5f, (float)rec.y + innerRadius + 0.5f}, // P5, P6, P7 {x3, y1}, // P7
{(float)rec.x + innerRadius + 0.5f, rec.y + 0.5f}, {x0, y4}, // P8
{(float)(rec.x + rec.width) - innerRadius - 0.5f, rec.y + 0.5f}, // P8, P9 {x1, y4}, // P9
{rec.x + rec.width - 0.5f, (float)rec.y + innerRadius + 0.5f}, {x4, y1}, // P10
{rec.x + rec.width - 0.5f, (float)(rec.y + rec.height) - innerRadius - 0.5f}, // P10, P11 {x4, y2}, // P11
{(float)(rec.x + rec.width) - innerRadius - 0.5f, rec.y + rec.height - 0.5f}, {x1, y5}, // P12
{(float)rec.x + innerRadius + 0.5f, rec.y + rec.height - 0.5f}, // P12, P13 {x0, y5}, // P13
{rec.x + 0.5f, (float)(rec.y + rec.height) - innerRadius - 0.5f}, {x5, y2}, // P14
{rec.x + 0.5f, (float)rec.y + innerRadius + 0.5f} // P14, P15 {x5, y1} // P15
}; };
const Vector2 centers[4] = { const Vector2 centers[4] = {
{(float)rec.x + innerRadius + 0.5f, (float)rec.y + innerRadius + 0.5f}, {x0, y1}, // P16
{(float)(rec.x + rec.width) - innerRadius - 0.5f, (float)rec.y + innerRadius + 0.5f}, // P16, P17 {x1, y1}, // P17
{(float)(rec.x + rec.width) - innerRadius - 0.5f, (float)(rec.y + rec.height) - innerRadius - 0.5f}, {x1, y2}, // P18
{(float)rec.x + innerRadius + 0.5f, (float)(rec.y + rec.height) - innerRadius - 0.5f} // P18, P19 {x0, y2} // P19
}; };
const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f }; const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f };
@ -1263,13 +1371,24 @@ void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Colo
void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float thick, Color color) void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float thick, Color color)
{ {
if (thick <= 0.0f) return;
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
float centralAngle = rotation*DEG2RAD; float centralAngle = rotation*DEG2RAD;
float exteriorAngle = 360.0f/(float)sides*DEG2RAD; float exteriorAngle = 360.0f/(float)sides*DEG2RAD;
float apothem = radius*cosf(DEG2RAD*180.0f/(float)sides); float apothem = radius*cosf(DEG2RAD*180.0f/(float)sides);
float innerRadius = fmaxf(0.0f, radius - thick*(radius/apothem));
float outerRadius = 0.0f;
float innerRadius = 0.0f;
if (thick >= 0.0f)
{
outerRadius = radius;
innerRadius = fmaxf(0.0f, radius - thick*(radius/apothem));
}
else
{
thick *= -1.0f;
outerRadius = radius + thick*(radius/apothem);
innerRadius = radius;
}
#if SUPPORT_QUADS_DRAW_MODE #if SUPPORT_QUADS_DRAW_MODE
rlSetTexture(GetShapesTexture().id); rlSetTexture(GetShapesTexture().id);
@ -1282,7 +1401,7 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl
float nextAngle = centralAngle + exteriorAngle; float nextAngle = centralAngle + exteriorAngle;
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius); rlVertex2f(center.x + cosf(centralAngle)*outerRadius, center.y + sinf(centralAngle)*outerRadius);
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius); rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius);
@ -1291,7 +1410,7 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl
rlVertex2f(center.x + cosf(nextAngle)*innerRadius, center.y + sinf(nextAngle)*innerRadius); rlVertex2f(center.x + cosf(nextAngle)*innerRadius, center.y + sinf(nextAngle)*innerRadius);
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height);
rlVertex2f(center.x + cosf(nextAngle)*radius, center.y + sinf(nextAngle)*radius); rlVertex2f(center.x + cosf(nextAngle)*outerRadius, center.y + sinf(nextAngle)*outerRadius);
centralAngle = nextAngle; centralAngle = nextAngle;
} }
@ -1304,13 +1423,13 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
float nextAngle = centralAngle + exteriorAngle; float nextAngle = centralAngle + exteriorAngle;
rlVertex2f(center.x + cosf(nextAngle)*radius, center.y + sinf(nextAngle)*radius); rlVertex2f(center.x + cosf(nextAngle)*outerRadius, center.y + sinf(nextAngle)*outerRadius);
rlVertex2f(center.x + cosf(centralAngle)*radius, center.y + sinf(centralAngle)*radius); rlVertex2f(center.x + cosf(centralAngle)*outerRadius, center.y + sinf(centralAngle)*outerRadius);
rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius); rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius);
rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius); rlVertex2f(center.x + cosf(centralAngle)*innerRadius, center.y + sinf(centralAngle)*innerRadius);
rlVertex2f(center.x + cosf(nextAngle)*innerRadius, center.y + sinf(nextAngle)*innerRadius); rlVertex2f(center.x + cosf(nextAngle)*innerRadius, center.y + sinf(nextAngle)*innerRadius);
rlVertex2f(center.x + cosf(nextAngle)*radius, center.y + sinf(nextAngle)*radius); rlVertex2f(center.x + cosf(nextAngle)*outerRadius, center.y + sinf(nextAngle)*outerRadius);
centralAngle = nextAngle; centralAngle = nextAngle;
} }