c++ - 如何对拉伸(stretch)的矩形进行斜切

标签 c++ math opengl glsl

我能够将矩形的角倒角。

enter image description here

当我拉伸(stretch)矩形并尝试将其倾斜时,结果看起来不平滑,它应该看起来像右侧的矩形。

enter image description here

当矩形拉伸(stretch)时,如何计算三角形扇形的点?

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

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);
}

应用 Soultion 后,这是我得到的结果。 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

最佳答案

你有一个宽度为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 分量,在底部,dx 分量中减去em> 角点的分量:

 (-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

关于c++ - 如何对拉伸(stretch)的矩形进行斜切,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59451035/

相关文章:

c++ - 使用PTS同步FFMPEG视频帧

c++ - C++中 "int a(); "有什么作用?

java - 求圆心与圆心的夹角

python - 绘制具有不同 x 值和不同 n 值的数学函数 f(x)

c - Mingw w64 的链接器在搜索 -lglut32 new 时跳过不兼容

opengl - glUseProgram(0) 需要 50 毫秒?

android - YUV (NV21) 到移动设备上的 BGR 转换( native 代码)

c++ - 使用 std::stringstream 转换为字符串在空格处失败

c++ - makefile中的多种编译模式

math - 在什么情况下需要多项式的泰勒级数?