Search code examples
c++openglglm-math

How to create outline


I have a set of points , which is in shape of a line.

enter image description here

How can we create new set of points which would be at a offset distance from the current set of points and using GL_TRIANGLE_STRIP we would be able to create a polygon shape.

enter image description here

This is my current code but I could not get any meaningful result from it.

// outlineVertices are existing set of points from which we would generate the offsetPoints

for (int i = 0; i < outlineVertices.size() - 3 ; i += 3) {
        finalVertices.push_back(outlineVertices[i]);
        finalVertices.push_back(outlineVertices[i + 1]);
        finalVertices.push_back(outlineVertices[i + 2]);        

        glm::vec3 point1 = glm::vec3(outlineVertices[i], outlineVertices[i + 1], outlineVertices[i + 2]);
        glm::vec3 point2 = glm::vec3(outlineVertices[i + 7], outlineVertices[i + 1 + 7], outlineVertices[i + 2 + 7]);
        glm::vec4 directionVector = GetPerpendicularVectorDirection(point1, point2);
    
        finalVertices.push_back(outlineVertices[i] - (directionVector.x * outlineWidth ));
        finalVertices.push_back(outlineVertices[i + 1] + (directionVector.y * outlineWidth));
        finalVertices.push_back(outlineVertices[i + 2]);
        finalVertices.push_back(outlineVertices[i + 3]);
        
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

glm::vec4 RectangleOutline::GetPerpendicularVectorDirection(glm::vec3 point1, glm::vec3 point2) {

    glm::vec3 Direction = glm::normalize(point1 - point2);
    float x, y;
    x = Direction.x;
    Direction.x = -y;
    Direction.y = x;
    return glm::vec4(Direction, 0);
}

Solution

  • You have to compute the Miter joint between 2 line segments. To do this, you need to calculate the vectors along the line segments to be connected. Calculate the normalized normal vectors to the line segments. The vector along the miter joint is the sum of the normal vectors. (You can even do this in the vertex shader: OpenGL Line Width)

    If you have 3 points (p1, p2, p3)

    p1       p2
      +-----+
             \
              \
               +
                 p3
    

    then the normal vector along the miter joint in p2 is:

    // vectors along the line
    glm::vec2 v12 = p2 - p1;
    glm::vec2 v23 = p3 - p2;
    
    // normalized normal vectors to the line segments
    glm::vec2 vn12 = glm::normlalize(glm::vec2(-v12.y, v12.x));
    glm::vec2 vn23 = glm::normlalize(glm::vec2(-v23.y, v23.x));
    
    // normalized vector along miter joint
    glm::vec2 vm2 = glm::normalize(vn12 + vn23);
    

    and the points (pa, pb) on the joint are:

              pa
        -----+
         p2 / \
      -----+    \
          / \
    -----+    \
      pb  \
            \
    
    float d = thickness / glm::dot(vm2, vn12);
    
    glm::vec2 pa = p2 + vm2 * d/2;
    glm::vec2 pb = p2 - vm2 * d/2;