[rshapes] Updated DrawRectangleRoundedLinesEx().
Lines used to draw outside when `thick` was positive. Added support for negative `thick` values. When `thick` is negative, lines are drawn growing outside of the rectangle.
This commit is contained in:
parent
5ee499ebff
commit
a0b253092e
1 changed files with 74 additions and 25 deletions
101
src/rshapes.c
101
src/rshapes.c
|
|
@ -1009,32 +1009,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,
|
||||||
|
|
@ -1054,20 +1103,20 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// The x-coordinates used for the outline
|
// The x-coordinates used for the outline
|
||||||
const float x0 = (float)rec.x + innerRadius + 0.5f;
|
const float x0 = rec.x + outerRadius;
|
||||||
const float x1 = (float)(rec.x + rec.width) - innerRadius - 0.5f;
|
const float x1 = (rec.x + rec.width) - outerRadius;
|
||||||
const float x2 = rec.x + rec.width + thick - 0.5f;
|
const float x2 = rec.x + rec.width;
|
||||||
const float x3 = rec.x - thick + 0.5f;
|
const float x3 = rec.x;
|
||||||
const float x4 = rec.x + rec.width - 0.5f;
|
const float x4 = rec.x + rec.width - roundedOutlineThick;
|
||||||
const float x5 = rec.x + 0.5f;
|
const float x5 = rec.x + roundedOutlineThick;
|
||||||
|
|
||||||
// The y-coordinates used for the outline
|
// The y-coordinates used for the outline
|
||||||
const float y0 = rec.y - thick + 0.5f;
|
const float y0 = rec.y;
|
||||||
const float y1 = (float)rec.y + innerRadius + 0.5f;
|
const float y1 = rec.y + outerRadius;
|
||||||
const float y2 = (float)(rec.y + rec.height) - innerRadius - 0.5f;
|
const float y2 = (rec.y + rec.height) - outerRadius;
|
||||||
const float y3 = rec.y + rec.height + thick - 0.5f;
|
const float y3 = rec.y + rec.height;
|
||||||
const float y4 = rec.y + 0.5f;
|
const float y4 = rec.y + roundedOutlineThick;
|
||||||
const float y5 = rec.y + rec.height - 0.5f;
|
const float y5 = rec.y + rec.height - roundedOutlineThick;
|
||||||
|
|
||||||
const Vector2 point[16] = {
|
const Vector2 point[16] = {
|
||||||
{x0, y0}, // P0
|
{x0, y0}, // P0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue