【问题标题】:How to bevel a stretched rectangle如何斜切拉伸的矩形
【发布时间】:2019-12-23 06:32:21
【问题描述】:

我可以斜切矩形的角。

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

当矩形被拉伸时如何计算三角形扇形的点?

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

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

应用灵魂之后,这是我得到的结果。

//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,
    };

【问题讨论】:

  • 您需要对顶点执行此操作吗?我和你有同样的问题,我的解决方案是制作一个矩形并给每个顶点一个法线并在片段着色器中计算它。它看起来也会更好,因为它将按片段而不是按顶点计算。
  • @Rhu Mage 是的,我需要对顶点执行此操作,因为我也会挤出此几何体。

标签: c++ math opengl glsl


【解决方案1】:

你有一个矩形,宽度为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

【讨论】:

  • 感谢 Rabbid76 我尝试了您的解决方案,但仍然无法正常工作我已用您的解决方案更新了问题
  • 我已经更新了代码请看一下,我试过 float fscale = 1.0f + y / (float) 但它现在确实有效。
  • @shomit 你的矩形的高度是yHeight*2。所以它必须是fscale = y / yHeight;
  • 我试过 fscale = y / yHeight 但还是和之前的结果一样。
  • 当我查看您问题中的图片时,四舍五入似乎是正确的,但(半)右边缘似乎是错误的。它不平行于左边缘。
猜你喜欢
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
相关资源
最近更新 更多