epezent / implot

Immediate Mode Plotting
MIT License
4.5k stars 495 forks source link

Point graphs linkage #573

Open RampantDespair opened 1 month ago

RampantDespair commented 1 month ago

I'm new to ImPlot, so perhaps I'm misunderstanding / misusing the DragPoint mechanism. But I have 2 separate plots and for a reason I do not understand, some of the points inside each graph are linked to each other...

        ImPlotFlags plot_flags = ImPlotFlags_CanvasOnly | ImPlotFlags_Equal | ImPlotFlags_Crosshairs;
        ImPlotAxisFlags axis_flags = ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoSideSwitch;

        if (ImPlot::BeginPlot("Bezier Quadratic", { 250, 250 }, plot_flags))
        {
            ImPlot::SetupAxes(NULL, NULL, axis_flags, axis_flags);

            static std::array<glm::dvec2, 3> control_points_quadratic = { 
                glm::dvec2{ 0.0, 0.0 }, 
                glm::dvec2{ 0.5, 0.5 },
                glm::dvec2{ 1.0, 1.0 } 
            };

            for (int i = 0; i < 3; i++)
            {
                control_points_quadratic[i] = glm::clamp(control_points_quadratic[i], glm::dvec2{ 0.0, 0.0 }, glm::dvec2{ 1.0, 1.0 });
                ImPlot::DragPoint(
                    i, 
                    &control_points_quadratic[i].x, 
                    &control_points_quadratic[i].y, 
                    { 0.f, 0.f, 0.f, 1.f }, 5.f, 
                    (i == 0 || i == 2 ? ImPlotDragToolFlags_NoInputs : ImPlotDragToolFlags_None)
                );
            }

            std::array<ImPlotPoint, 101> points = {};

            for (int i = 0; i <= 100; i++)
            {
                double t = i / 100.0;

                glm::dvec2 l0 = (1.0 - t) * control_points_quadratic[0] + t * control_points_quadratic[1];
                glm::dvec2 l1 = (1.0 - t) * control_points_quadratic[1] + t * control_points_quadratic[2];
                glm::dvec2 q0 = (1.0 - t) * l0 + t * l1;

                points[i] = ImPlotPoint(q0.x, q0.y);
            }

            ImPlot::PlotLine("##quad", &points[0].x, &points[0].y, 101, 0, 0, sizeof(ImPlotPoint));

            ImPlot::EndPlot();
        }

        ImGui::SameLine();

        if (ImPlot::BeginPlot("Bezier Cubic", { 250, 250 }, plot_flags))
        {
            ImPlot::SetupAxes(NULL, NULL, axis_flags, axis_flags);

            static std::array<glm::dvec2, 4> control_points_cubic = {
                glm::dvec2{ 0.0, 0.0 },
                glm::dvec2{ 0.3, 0.3 },
                glm::dvec2{ 0.6, 0.6 },
                glm::dvec2{ 1.0, 1.0 }
            };

            for (int i = 0; i < 4; i++)
            {
                control_points_cubic[i] = glm::clamp(control_points_cubic[i], glm::dvec2{ 0.0, 0.0 }, glm::dvec2{ 1.0, 1.0 });
                ImPlot::DragPoint(
                    i,
                    &control_points_cubic[i].x,
                    &control_points_cubic[i].y,
                    { 0.f, 0.f, 0.f, 1.f }, 5.f,
                    (i == 0 || i == 3 ? ImPlotDragToolFlags_NoInputs : ImPlotDragToolFlags_None)
                );
            }

            std::array<ImPlotPoint, 101> points = {};

            for (int i = 0; i <= 100; i++)
            {
                double t = i / 100.0;

                glm::dvec2 l0 = (1.0 - t) * control_points_cubic[0] + t * control_points_cubic[1];
                glm::dvec2 l1 = (1.0 - t) * control_points_cubic[1] + t * control_points_cubic[2];
                glm::dvec2 l2 = (1.0 - t) * control_points_cubic[2] + t * control_points_cubic[3];
                glm::dvec2 q0 = (1.0 - t) * l0 + t * l1;
                glm::dvec2 q1 = (1.0 - t) * l1 + t * l2;
                glm::dvec2 c0 = (1.0 - t) * q0 + t * q1;

                points[i] = ImPlotPoint(c0.x, c0.y);
            }

            ImPlot::PlotLine("##cubic", &points[0].x, &points[0].y, 101, 0, 0, sizeof(ImPlotPoint));

            ImPlot::EndPlot();
        }

https://github.com/epezent/implot/assets/63611551/5a29c65e-8a41-4b1c-beca-e1b291cee509

Any help or recommendations are appreciated.