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

draw_polyline The display intermittently breaks when two points jump too much,but Using draw line will not appear #96573

Open
Caesar454905970 opened this issue Sep 4, 2024 · 7 comments

Comments

@Caesar454905970
Copy link

Caesar454905970 commented Sep 4, 2024

Tested versions

Godot Engine v4.3.stable.

System information

Window10 godot-cpp4.3

Issue description

    // draw_line 当巨大跳跃不会出现  间断点
    //but Using draw line will not appear
    // for (const auto &array : points)
    // {
    //     if (array.size() >= 2) // 确保至少有2个点
    //     {
    //         for (size_t i = 1; i < array.size(); ++i)
    //         {
    //             draw_line(array[i - 1], array[i], lineColor, line_thickness);
    //         }
    //     }
    // }



    // draw_polyline 当巨大跳跃 会出现间断点
    //draw_polyline The display intermittently breaks when two points jump too much
    for (const auto &array : points)
    {
        if (array.size() >= 2) // 确保至少有2个点
        {
            PackedVector2Array packed_array;
            for (const auto &point : array)
            {
                packed_array.push_back(point);
            }
            draw_polyline(packed_array, lineColor, line_thickness, antialiased);
        }
    }

mark time :01:13:51
c7323af0f94d75cc31b9e37b5682db8
9526a93140a96751f0d61ad2daaaa40

Steps to reproduce

void waveformRendering::_draw()
{
    if (mapped_view_to_ecgrawDat == NULL)
    {
        UtilityFunctions::print("File not mapped");
        return;
    }

    char *current_position = mapped_view_to_ecgrawDat + m_drawline_start_index * 36;

    points.clear();
    points.resize(12); // 预先分配空间

    float y_Translate_item = 100.0;
    std::vector<float> lead_translates(12);
    for (int i = 0; i < 12; ++i)
    {
        lead_translates[i] = 100.0 + i * y_Translate_item;
    }

    float m_x_line_standard_gain = 1.0;
    float m_y_line_standard_gain = 1.0;
    float InputScalar_y_line_standard_gain = 0.100;

    if (current_position != NULL)
    {
        for (int i = 0; i < sampling_number; i++)
        {
            float x = i * m_x_line_standard_gain * 0.25;

            for (int j = 0; j < 12; j++)
            {
                unsigned char low4 = static_cast<unsigned char>(current_position[0]) & 0x0F;
                unsigned short low16 = (static_cast<unsigned char>(current_position[1]) << 8) |
                                       static_cast<unsigned char>(current_position[2]);
                short tmp1 = (low4 << 16) | low16;

                float y = tmp1 * m_y_line_standard_gain * (-1) * InputScalar_y_line_standard_gain + lead_translates[j];

                points[j].emplace_back(x, y);

                current_position += 3;
            }

            if ((i + m_drawline_start_index) % 500 == 0)
            {
                Vector2 component_size = get_size();
                int timestamp = (i + m_drawline_start_index) * 2;
                String timestamp_text = convert_from_timestamp_hh_mm_ss(timestamp);
                float text_width = default_font->get_string_size(timestamp_text).x;
                Vector2 text_position = Vector2(x - text_width / 2 - 8, component_size.y - 20);

                draw_string(default_font, text_position, U"" + (timestamp_text), HORIZONTAL_ALIGNMENT_CENTER, -1, 20.0, godot::Color(0, 0, 0));
                draw_line(Vector2(x, component_size.y - 20), Vector2(x, component_size.y), Color(0, 0, 0), 2.0);
            }
        }
    }

    Color lineColor(0, 0, 0);
    float line_thickness = 1.0;
    bool antialiased = false;

    // draw_line 当巨大跳跃不会出现  间断点
    //but Using draw line will not appear
    // for (const auto &array : points)
    // {
    //     if (array.size() >= 2) // 确保至少有2个点
    //     {
    //         for (size_t i = 1; i < array.size(); ++i)
    //         {
    //             draw_line(array[i - 1], array[i], lineColor, line_thickness);
    //         }
    //     }
    // }



    // draw_polyline 当巨大跳跃 会出现间断点
    //draw_polyline The display intermittently breaks when two points jump too much
    for (const auto &array : points)
    {
        if (array.size() >= 2) // 确保至少有2个点
        {
            PackedVector2Array packed_array;
            for (const auto &point : array)
            {
                packed_array.push_back(point);
            }
            draw_polyline(packed_array, lineColor, line_thickness, antialiased);
        }
    }
}

Minimal reproduction project (MRP)

src.zip

@aXu-AP
Copy link
Contributor

aXu-AP commented Sep 8, 2024

Maybe you can condense the MRP just to a few lines to see exactly where the problem lies?
Something like:

extends Node2D
func _draw():
    draw_polyline([this point, that point], Color.WHITE) # Insert the points that cause problem

@Caesar454905970
Copy link
Author

game.zip
This is a small test data project that can reproduce this problem
image

@Caesar454905970
Copy link
Author

You can locate it through my project, i=9405!
image

@Caesar454905970
Copy link
Author

也许你可以将 MRP 压缩为几行来准确查看问题所在? 例如:

extends Node2D
func _draw():
    draw_polyline([this point, that point], Color.WHITE) # Insert the points that cause problem

i do it that you can see.

@Caesar454905970
Copy link
Author

`extends Control

func _ready() -> void:
queue_redraw() # 请求重绘

func _process(delta: float) -> void:
pass

func float_array_to_Vector2Array(arr: Array) -> Array:
var vec_array = []
for point in arr:
vec_array.append(Vector2(point[0], point[1]))
return vec_array

func _draw() -> void:
var line_color = Color(0, 0, 0) # 黑色
var line_thickness = 1.0
var coords_mouth = [
[2349.75, 101],
[2350, 102.4],
[2350.25, 103.4],
[2350.5, 102.9],
[2350.75, 102.9],
[2360, 102.9],
[2360.25, 97],
[2360.5, 125.4],
[2360.75, 125.4],
[2370.0, 125.4],
[2370.25, 126.4],
[2375, 127.3],
[2370.75, 128.3],
]

draw_polyline(float_array_to_Vector2Array(coords_mouth), line_color, line_thickness)

print("_draw success111")

`
image

@aXu-AP
Copy link
Contributor

aXu-AP commented Sep 9, 2024

I see it now. I guess what's happening is that at a certain angle, the line never covers some pixels enough to be drawn (due to floating point errors?). I'm not sure if it is something that is fixable in engine, because it is expected for too thin lines without antialiasing to disappear.
I suggest any of the following solutions:

  • Use default line width - this draws the line always 1 px thin regardless of the zoom level and shouldn't create any gaps
  • Tweak the line width to something like 1.01 - this could help with the edge cases, but at some points it might make the line thicker
  • Enable antialiasing to draw subpixel lines (last argument to draw_polyline) - this mostly works but there's some limit how thin the lines can go still.

@Caesar454905970
Copy link
Author

Thank you very much. I've tried your method and it works,

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