一、三角形质心坐标
对于三角形ABC及其内一点P,根据三角形质心坐标,有如下关系
Px = i * Ax + j * Bx + k * Cx;
Py = i * Ay + j * By + k * Cy;
其中 i + j + k = 1
利用该关系,可以通过遍历i,j,k值实现遍历三角形内所有的点
void triangle_enum(int xy[6])
{
int max = 100; //设定一个精度范围
int i, j, k;
for (i = 0; i < max; i++)
{
for (j = 0; j < max - i; j++)
{
k = max - i - j;
//输出坐标
x = (i * xy[0] + j * xy[2] + k * xy[4]) / max;
y = (i * xy[1] + j * xy[3] + k * xy[5]) / max;
}
}
}
二、图片拉伸和渲染
我们的图片素材一般为矩形,而矩形又可以分割为2个到多个三角形,通过矩形顶点和三角形顶点的匹配,可以把i,j,k三个顶点权重值用到矩形中来,实现对矩形图片中的像素的定位。
假设现有矩形ABCD,可以拆分成三角形ABC和三角形CDA依次渲染,先画三角形ABC部分;现在定好了拉伸后输出到画布的三个坐标为xy[6],把该数组传入上面的 triangle_enum 函数即可枚举出要在画布上填充的点,那么这些点对应矩形图片中的点又是哪些呢?
已知xy[6]是相对于画布的坐标,我们可以再定义一个数组xy2[6]作为相对于矩形图片中的坐标,很显然数值如下
//图片左上角像素坐标,对应顶点A
xy2[0] = 0;
xy2[1] = 0;
//图片右上角像素坐标,对应顶点B
xy2[2] = 图片宽 - 1;
xy2[3] = 0;
//图片右下角像素坐标,对应顶点C
xy2[4] = 图片宽 - 1;
xy2[5] = 图片高 - 1;
把xy2[6]也传入函数 triangle_enum,同样用i,j,k权重处理,即可得到相对矩形图片中的像素位置。
void triangle_enum(int xy[6], int xy2[6])
{
int max = 100; //设定一个精度范围
int i, j, k;
int x, y;
int x2, y2;
for (i = 0; i < max; i++)
{
for (j = 0; j < max - i; j++)
{
k = max - i - j;
//输出到画布的的坐标
x = (i * xy[0] + j * xy[2] + k * xy[4]) / max;
y = (i * xy[1] + j * xy[3] + k * xy[5]) / max;
//对应矩形图片中的坐标
x2 = (i * xy2[0] + j * xy2[2] + k * xy2[4]) / max;
y2 = (i * xy2[1] + j * xy2[3] + k * xy2[5]) / max;
//两边坐标都知道了,开始画RGB颜色点
画布[y][x][r] = 图片[y2][x2][r];
画布[y][x][g] = 图片[y2][x2][g];
画布[y][x][b] = 图片[y2][x2][b];
}
}
}
三、测试效果
1. 随机三角形填充
由于三个顶点坐标都是随机生成的,这里用颜色和i,j,k权重处理后进行标记,顶点顺序依次对应红、绿、蓝
2. 图片拉伸和渲染
为了防止出现凹四边形、图片反转,这里固定了左上、右下两个顶点,只动左下和右上顶点。
测试代码:
https://gitee.com/wexiangis/pic_stretch
参考资料:
https://www.cnblogs.com/calence/p/9982369.html
https://blog.youkuaiyun.com/weixin_34304013/article/details/89063136