Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PathArcTo no longer accepts counter-clockwise arcs #4030

Closed
sturnclaw opened this issue Apr 10, 2021 · 4 comments
Closed

PathArcTo no longer accepts counter-clockwise arcs #4030

sturnclaw opened this issue Apr 10, 2021 · 4 comments

Comments

@sturnclaw
Copy link

sturnclaw commented Apr 10, 2021

Version/Branch of Dear ImGui:

Version: 1.82
Branch: master on tag v1.82

Back-end/Renderer/Compiler/OS

Back-ends: OpenGL3 + SDL2
Compiler: GNU GCC 10.2.0
Operating System: Solus Linux

My Issue/Question:

With commit e45847d, ImDrawList::PathArcTo (and more specifically ImDrawList::_PathArcToN) asserts that a_min <= a_max, enforcing clockwise path arc order. This breaks the code in #434, and more specifically breaks production code in Pioneer which is using drawing commands almost identical to Horrowind's code in the above issue.

The below code (sorry, it's long) works perfectly as long as that assertion in _PathArcToN is commented out, and has worked since at least ImGui 1.6x. I'd like to see a more general fix for this issue that re-enables counter-clockwise arcs using the auto-tessellated PathArcTo function, or at least some support in the DrawList API for drawing wide partial arcs with uniform thickness gaps between them.

Screenshots/Video

image

Standalone, minimal, complete and verifiable example:

const float RADIUS_MIN = 20.0f;
const float RADIUS_MAX = 90.0f;
const int ITEMS_MIN = 4;

ImVec2 center = { 110.f, 110.f };
ImDrawList *draw_list = ImGui::GetWindowDrawList();
draw_list->PushClipRectFullScreen();
draw_list->PathArcTo(center, (RADIUS_MIN + RADIUS_MAX) * 0.5f, 0.0f, IM_PI * 2.0f * 0.99f);
draw_list->PathStroke(ImColor(18, 44, 67, 210), true, RADIUS_MAX - RADIUS_MIN);

const float item_arc_span = 2 * IM_PI / ITEMS_MIN;

for (size_t item_n = 0; item_n < ITEMS_MIN; item_n++) {
    const float inner_spacing = ImGui::GetStyle().ItemInnerSpacing.x / RADIUS_MIN / 2;
    const float item_inner_ang_min = item_arc_span * (item_n - 0.5f + inner_spacing);
    const float item_inner_ang_max = item_arc_span * (item_n + 0.5f - inner_spacing);
    const float item_outer_ang_min = item_arc_span * (item_n - 0.5f + inner_spacing * (RADIUS_MIN / RADIUS_MAX));
    const float item_outer_ang_max = item_arc_span * (item_n + 0.5f - inner_spacing * (RADIUS_MIN / RADIUS_MAX));

    int arc_segments = static_cast<int>((64 * item_arc_span / (2 * IM_PI))) + 1;
    draw_list->_PathArcToN(center, RADIUS_MAX, item_outer_ang_min, item_outer_ang_max, arc_segments);
    draw_list->_PathArcToN(center, RADIUS_MIN, item_inner_ang_max, item_inner_ang_min, arc_segments);
    draw_list->PathFillConvex(ImColor(102, 147, 189, 140));
}
draw_list->PopClipRect();
@thedmd
Copy link
Contributor

thedmd commented Apr 12, 2021

I want to let you know, I'm working on a fix to that. Issue should be addressed soon.

Sorry for inconvenience.

@sturnclaw
Copy link
Author

I want to let you know, I'm working on a fix to that. Issue should be addressed soon.
Sorry for inconvenience.

Thank you! No inconvenience at all, I know full well that it's not an "intended" feature to draw concave shapes, but this method is a lot easier than trying to add an efficient, general-purpose concave polygon triangulation algorithm.

@thedmd
Copy link
Contributor

thedmd commented Apr 15, 2021

Arc functions now handle counter-clockwise direction.

@ocornut
Copy link
Owner

ocornut commented Apr 15, 2021

Thank you @thedmd for the fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants