Skip to content

Commit e3d9b87

Browse files
Leonardo Serranoocornut
Leonardo Serrano
authored andcommitted
ImDrawList: added PathEllipticalArcTo(), AddEllipse(), AddEllipseFilled(). (#2743)
Rebased with mods by ocornut: defaults to num_segments==0, supports for auto-tesselation, tweak demo.
1 parent fa2e571 commit e3d9b87

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

docs/CHANGELOG.txt

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Other changes:
5050
- MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously
5151
register contents size in a way that would affect the scrolling layer.
5252
Was most often noticable when using an horizontal scrollbar. (#6789)
53+
- ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl]
5354
- Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99]
5455

5556

imgui.h

+3
Original file line numberDiff line numberDiff line change
@@ -2675,6 +2675,8 @@ struct ImDrawList
26752675
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0);
26762676
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);
26772677
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
2678+
IMGUI_API void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f);
2679+
IMGUI_API void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0);
26782680
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
26792681
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
26802682
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
@@ -2699,6 +2701,7 @@ struct ImDrawList
26992701
inline void PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, flags, thickness); _Path.Size = 0; }
27002702
IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0);
27012703
IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
2704+
IMGUI_API void PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments = 0); // Ellipse
27022705
IMGUI_API void PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points)
27032706
IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)
27042707
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0);

imgui_demo.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -7772,6 +7772,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
77727772
float th = (n == 0) ? 1.0f : thickness;
77737773
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
77747774
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
7775+
draw_list->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, sz*0.3f, col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse
77757776
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, ImDrawFlags_None, th); x += sz + spacing; // Square
77767777
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, ImDrawFlags_None, th); x += sz + spacing; // Square with all rounded corners
77777778
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
@@ -7792,8 +7793,9 @@ static void ShowExampleAppCustomRendering(bool* p_open)
77927793
x = p.x + 4;
77937794
y += sz + spacing;
77947795
}
7795-
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // N-gon
7796-
draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments); x += sz + spacing; // Circle
7796+
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, ngon_sides); x += sz + spacing; // N-gon
7797+
draw_list->AddCircleFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, circle_segments); x += sz + spacing; // Circle
7798+
draw_list->AddEllipseFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, sz * 0.3f, col, -0.3f, circle_segments); x += sz + spacing;// Ellipse
77977799
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square
77987800
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
77997801
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
@@ -7804,7 +7806,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
78047806
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine)
78057807
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
78067808

7807-
ImGui::Dummy(ImVec2((sz + spacing) * 10.2f, (sz + spacing) * 3.0f));
7809+
ImGui::Dummy(ImVec2((sz + spacing) * 11.2f, (sz + spacing) * 3.0f));
78087810
ImGui::PopItemWidth();
78097811
ImGui::EndTabItem();
78107812
}

imgui_draw.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,27 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
12171217
}
12181218
}
12191219

1220+
void ImDrawList::PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments)
1221+
{
1222+
if (num_segments <= 0)
1223+
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
1224+
1225+
_Path.reserve(_Path.Size + (num_segments + 1));
1226+
1227+
const float cos_rot = ImCos(rot);
1228+
const float sin_rot = ImSin(rot);
1229+
for (int i = 0; i <= num_segments; i++)
1230+
{
1231+
const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min);
1232+
ImVec2 point(ImCos(a) * radius_x, ImSin(a) * radius_y);
1233+
const float rel_x = (point.x * cos_rot) - (point.y * sin_rot);
1234+
const float rel_y = (point.x * sin_rot) + (point.y * cos_rot);
1235+
point.x = rel_x + center.x;
1236+
point.y = rel_y + center.y;
1237+
_Path.push_back(point);
1238+
}
1239+
}
1240+
12201241
ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
12211242
{
12221243
float u = 1.0f - t;
@@ -1547,6 +1568,35 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in
15471568
PathFillConvex(col);
15481569
}
15491570

1571+
// Ellipse
1572+
void ImDrawList::AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments, float thickness)
1573+
{
1574+
if ((col & IM_COL32_A_MASK) == 0)
1575+
return;
1576+
1577+
if (num_segments <= 0)
1578+
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
1579+
1580+
// Because we are filling a closed shape we remove 1 from the count of segments/points
1581+
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
1582+
PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1);
1583+
PathStroke(col, true, thickness);
1584+
}
1585+
1586+
void ImDrawList::AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments)
1587+
{
1588+
if ((col & IM_COL32_A_MASK) == 0)
1589+
return;
1590+
1591+
if (num_segments <= 0)
1592+
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
1593+
1594+
// Because we are filling a closed shape we remove 1 from the count of segments/points
1595+
const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
1596+
PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1);
1597+
PathFillConvex(col);
1598+
}
1599+
15501600
// Cubic Bezier takes 4 controls points
15511601
void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments)
15521602
{

0 commit comments

Comments
 (0)