如何斜切拉伸矩形

时间:2019-12-23 06:32:21

标签: c++ math opengl glsl

我能够倒角一个矩形的角。

enter image description here

当我拉伸矩形并尝试使其斜切时,结果看起来并不平滑,应该看起来像右侧的矩形。

enter image description here

在拉长矩形时,如何计算三角风扇的点?

当前,这是我计算四分之一圆的点的方法。

std::vector<float> bevelData;
bevelData.push_back(0.0); // First set the centre of the rectangle to the data
bevelData.push_back(0.0);
bevelData.push_back(0.0);
bevelData.push_back(0);
bevelData.push_back(0);
bevelData.push_back(1);
bevelData.push_back(0);
bevelData.push_back(0);
for (int i = 0; i <= segments; ++i) {
    float x, y;
    float angle = start_angle +  0.5 * M_PI * i / static_cast<float>(segments);
    x = circX + cos(angle) * rad;  // circX is the centre of the circle as marked in yellow in the first image 
    y = circY + sin(angle) * rad;  // circY is the centre of the circle as marked in yellow in the first image , rad is the radius of the circle
    bevelData.push_back(x);
    bevelData.push_back(y);
    bevelData.push_back(0.0);
    bevelData.push_back(0);
    bevelData.push_back(0);
    bevelData.push_back(1);
    bevelData.push_back(0);
    bevelData.push_back(0);
}

施加灵魂之后,这就是我得到的结果。 enter image description here

//Bevel Bottom Right
    float rightWidthBottom = (width / 2) - rightBottomBevel;
    float rightHeightBottom = (height / 2) - rightBottomBevel;
    std::vector<float> bottomRightBevelData = draw_bevel(rightWidthBottom, rightHeightBottom, rightBottomBevel, 1, -1, iSegmentsRightBottom);



std::vector<float> SuperRectangle::draw_bevel(float p_x, float p_y, float rad, int dir_x, int dir_y , int segments)
{
    std::vector<float> bevelData;
    float c_x, c_y;   // the center of the circle
    float start_angle; // the angle where to start the arc
    bevelData.push_back(0.0);
    bevelData.push_back(0.0);
    bevelData.push_back(0.0);
    bevelData.push_back(0);
    bevelData.push_back(0);
    bevelData.push_back(1);
    bevelData.push_back(0);
    bevelData.push_back(0);
    c_x = p_x  * dir_x;
    c_y = p_y  * dir_y;
    if (dir_x == 1 && dir_y == 1)
        start_angle = 0.0;
    else if (dir_x == 1 && dir_y == -1)
        start_angle = -M_PI * 0.5f;
    else if (dir_x == -1 && dir_y == 1)
        start_angle = M_PI * 0.5f;
    else if (dir_x == -1 && dir_y == -1)
        start_angle =  M_PI;
    for (int i = 0; i <= segments; ++i) {
        float x, y;
        float angle = start_angle +  0.5 * M_PI * i / static_cast<float>(segments);
        x = c_x + cos(angle) * rad;
        y = c_y + sin(angle) * rad;
        float fscale = (y / (float)(height / 2.0f));        
        x =  (x + (strech * fscale));
        bevelData.push_back(x);
        bevelData.push_back(y);
        bevelData.push_back(0.0);
        bevelData.push_back(0);
        bevelData.push_back(0);
        bevelData.push_back(1);
        bevelData.push_back(0);
        bevelData.push_back(0);
    }
    return bevelData;
}

///////////////////////////////////////////////// /////////////////

float xWidth  =  width / 2;
float yHeight  = height / 2;
float TriangleRight[] = {
        // positions               // Normals      // Texture Coord
         0.0f , 0.0f , 0.0f ,      0.0f,0.0,1.0,   0.0,0.0,  
         xWidth + strech ,  yHeight - rightTopBevel,0.0f,    0.0f,0.0,1.0 , 0.0,0.0,    
         xWidth - strech , -yHeight + rightBottomBevel,0.0f,    0.0f,0.0,1.0 , 0.0,0.0,   
    };


float TriangleLeft[] = {
        // positions      
         0.0f , 0.0f , 0.0f ,      0.0f,0.0,1.0,   0.0,0.0,
         -xWidth + strech  ,  yHeight - leftTopBevel ,0.0f,    0.0f,0.0,1.0 , 0.0,0.0,
        -xWidth - strech , -yHeight + leftBottomBevel,0.0f,    0.0f,0.0,1.0 , 0.0,0.0,
    };


float TriangleTop[] = {
        // positions      
         0.0f , 0.0f , 0.0f ,      0.0f,0.0,1.0,   0.0,0.0,
         xWidth - rightTopBevel + strech ,  yHeight ,0.0f,    0.0f,0.0,1.0 , 0.0,0.0,
         -xWidth + leftTopBevel + strech , yHeight,0.0f,    0.0f,0.0,1.0 , 0.0,0.0,
    };


float TriangleBottom[] = {
        // positions      
         0.0f , 0.0f , 0.0f ,      0.0f,0.0,1.0,   0.0,0.0,
         xWidth - rightBottomBevel - strech ,  -yHeight ,0.0f,    0.0f,0.0,1.0 , 0.0,0.0,
         -xWidth + leftBottomBevel - strech , -yHeight,0.0f,    0.0f,0.0,1.0 , 0.0,0.0,
    };

enter image description here

1 个答案:

答案 0 :(得分:4)

您有一个矩形,其宽度为w,高度为h

 (-w/2, h/2)                  (w/2, h/2)
            +----------------+
            |                |
            |                |
            |                |
            |                |
            +----------------+
(-w/2, -h/2)                  (w/2, -h/2)

矩形圆角的点计算如下:

x = circX + cos(angle) * rad;
y = circY + sin(angle) * rad;

然后将矩形移动d。在顶部d添加到拐角点的 x 组件,在底部d减去角落的 x 组件点:

 (-w/2 + d, h/2)                  (w/2 + d, h/2)
                 +----------------+
                /                /
               /                /
              /                /
             /                /
            +----------------+
(-w/2 - d, -h/2)                  (w/2 - d, -h/2)

您还必须将位移d应用于沿弧的点。必须相对于该点的 y 坐标缩放位移。
与靠近左边缘中心的点相比,靠近底边缘的点的位移必须更大:

x = circX + cos(angle) * rad
y = circY + sin(angle) * rad

scale = y / (h/2)
x = x - d * scale
相关问题