在opengl ES中画箭头

问题描述 投票:0回答:3

1)我知道箭头的起点,也知道终点。

我不知道如何画箭头的头部..我假设头部的其他两点与终点成45度角...

有人知道这样做所需的公式吗?

iphone opengl-es
3个回答
9
投票

Wade 对于这个问题的 OpenGL 部分给出了很好的答案;我将尝试回答向量数学部分。这是我脑海中的一些伪代码:

Triangle GenerateArrowHead(vec2 p1, vec2 p2)
{
    // Compute the vector along the arrow direction
    vec2 v = Normalize(p2 - p1)

    // Compute two perpendicular vectors to v
    vec2 vPerp1 = vec2(-v.y, v.x)
    vec2 vPerp2 = vec2(v.y, -v.x)

    // Compute two half-way vectors
    vec2 v1 = Normalize(v + vPerp1)
    vec2 v2 = Normalize(v + vPerp2)

    Triangle tri;
    tri.a = p2;
    tri.b = p2 + ArrowHeadSize * v1;
    tri.c = p2 + ArrowHeadSize * v2;
    return tri;
}

1
投票

为什么这不起作用?

1)为头部绘制一个三角形(意思是用GL_TRIANGLES绘制,而不是绘制形成三角形的3条线段)

2) 从三角形底边的中点延伸出一条线段。


0
投票

我最近实现了一个基本算法,它生成二维箭头的点并将其存储在传入的数组中,希望这可以帮助任何想要在 opengl 中创建健壮箭头的人:

/**
 * \brief Create the points of an arrow pointing from one point to another
 *
 *                                                g\
 *                                                | --\
 *                                                |    ---\
 *           |    a-------------------------------c        --\
 * stem      |    |                    -------/   |           --\
 * thickness |  start          -------/           |           -----end
 *           |    |    -------/                   |           --/
 *           |    b---/---------------------------d        --/
 *                                                |    ---/
 *                                                | --/
 *                                                f/
 *
 *                                                ------tip len-------
 *
 * returns [a, b, c, d, e, f, g] from this we want to produce indices
 *
 * {a, b, c}, {c, b, d}, {e, f, g}
 * {0, 1, 2}, {2, 1, 3}, {4, 5, 6}
 *
 * \author cuppajoeman (2024)
 */

void store_arrow_vertices(glm::vec2 start, glm::vec2 end, float stem_thickness, float tip_length, float *out_flattened_vertices) {

    float half_thickness = stem_thickness / (float) 2;

    glm::vec2 start_to_end = end - start;
    glm::vec2 end_to_start = start - end;

    float stem_length = std::max(0.0f, glm::length(start_to_end) - tip_length);

    glm::vec2 start_to_end_normalized = glm::normalize(start_to_end);
    glm::vec2 end_to_start_normalized = glm::normalize(end_to_start);

    // note that these two are also normalized
    glm::vec2 start_to_a_dir = glm::vec2(-start_to_end_normalized.y, start_to_end_normalized.x);
    glm::vec2 start_to_b_dir = glm::vec2(start_to_end_normalized.y, -start_to_end_normalized.x);

    glm::vec2 a = start + start_to_a_dir * half_thickness;
    glm::vec2 b = start + start_to_b_dir * half_thickness;
    glm::vec2 c = a + start_to_end_normalized * stem_length;
    glm::vec2 d = b + start_to_end_normalized * stem_length;

    /*
     *
     *         (aln)--        |
     *               ----     |
     *                  ----  |
     *         (e2s)----------s-------------e
     *                  ----  |
     *               ----     |
     *         (bln)--        |
     *
     *         ------len 1-----
     */

    glm::vec2 a_line = end_to_start_normalized + start_to_a_dir;
    glm::vec2 b_line = end_to_start_normalized + start_to_b_dir;

    /*
     *       |o
     *       |    o    hyp = \sqrt{2} x
     *       x        o
     *       |            o
     *       |------x------- o
     */

    a_line = glm::normalize(a_line) * (float) sqrt(2) * tip_length;
    b_line = glm::normalize(b_line) * (float) sqrt(2) * tip_length;

    glm::vec2 g = end + a_line;
    glm::vec2 f = end + b_line;


    const int num_flattened_vertices_in_arrow = 3 * 7;

    float arrow[num_flattened_vertices_in_arrow] = {
            a.x, a.y, 0.0f,
            b.x, b.y, 0.0f,
            c.x, c.y, 0.0f,
            d.x, d.y, 0.0f,
            end.x, end.y, 0.0f,
            f.x, f.y, 0.0f,
            g.x, g.y, 0.0f
    };

    for (int i = 0; i < num_flattened_vertices_in_arrow; i++) {
        out_flattened_vertices[i] = arrow[i];
    }

}

将其存储在顶点缓冲区后,我使用

glDrawElements
 的索引顺序调用 
{0, 1, 2}, {2, 1, 3}, {4, 5, 6}

来绘制它
© www.soinside.com 2019 - 2024. All rights reserved.