一、
在写风吹旗帜效果的时候,注意的是上一个点与下一个点的如Z坐标的关系,下一个点的Z坐标是上一个点的此时的Z坐标,其实就是按波的传递性来计算,Z坐标可以按任何曲线的函数来计算,如sin, cos,这只是最基本的思想,要做得真实,就看算法的了,但动态实现就是用坐标传递。
如把旗帜分成44行,44列,只计算Z坐标的传递,不考试X与Y,
那么,一共有45 * 45个点,每个点三个坐标值
const float PI = 3.1415;
const int row = 44; //要分成的行数
const int column = 44; // 要分成的列数
const float length = 9; //旗帜的长度
const disx = length / (float)column;
const disy = length / (float)row;
float coord[row][column][3];
// 按行逐行计算坐标值
for (int i=0; i < row; i++) {
float y = i * disy - length / 2.0;
for (int j=0; j < column; j++) {
coord[i][j][0] = j * disx - length / 2.0; //是为了保证旗帜处于正中间
coord[i][j][1] = y;
coord[i][j][2] = sin((float)j / (float)colum * 2.0 * PI);
// 注意除法时要不要把两个数都是整数
}
}
传递Z坐标
for (int i=0; i < row; i++) {
float hold = coord[i][0][2]; //保存第一个点的Z坐标,最后一个点要使用
for (int j=0; j < column-1; j++) {
coord[i][j][2] = coord[i][j+1][2];
}
coord[i][column-1] = hold;
}
这是最简单的计算,每一列的Z坐标都相同,重复了最后一个点的Z坐标与第一个点的Z坐标,还可以把列点的Z坐标按照一定的曲线方程来计算,然后把它传递给下一个点,还有X与Z坐标也有可能会变化,这里都是最简单的形式。
二、
为了能使Z轴即能在垂直方向运动,又能在水平方向运动,则需要两个数组来保存水平方向和垂直方向的Z坐标值。然后Z坐标为这两个坐标值的合成:
const int row = 45;
const int column = 45;
const float width= 9.0f;
const float height = 9.0f;
float coord[row][column][3]; // Flag的坐标
float hzcoord[row][column]; // Flag的Z坐标水平分量
float vzcoord[column][row]; // Flag的Z坐标垂直分量
//计算Z坐标的水平分量
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
hzcoord[i][j] = sin((float)j / (float)column * 360 * 3.1415 / 180);
}
}
//计算Z坐标的垂直分量
for (int i = 0; i < column; i++) {
for (int j = 0; j < row; j++) {
vzcoord[i][j] = sin((float)j / (float)column * 360 * 3.1415 / 180);
}
}
float disx = width / column;
float disy = height /row;
//计算每个点的坐标
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
coord[i][j][0] = j * disx - width / 2.0;
coord[i][j][1] = i * disy - height / 2.0;
coord[i][j][2] = hzcoord[i][j] + vzoord[j][i];
}
}
上面已经完成初始化每个点的坐标,下面就到了动态的每一帧时Z坐标的传递了:
//水平坐标分量的传递
for (int i = 0; i < row; i++) {
float hold = hzcoord[i][0];
for (int j = 0; j < column - 1; j++) {
hzcoord[i][j] = hzcoord[i][j+1];
}
hzcoord[i][column-1] = hold;
}
//垂直坐标分量的传递
for (int i = 0; i < column; i++) {
float hold = vzcoord[i][0];
for (int j = 0; j < row - 1; j++) {
vzcoord[i][j] = vzcoord[i][j+1];
}
vzcoord[i][row-1] = hold;
}
//每一帧时要计算的每个点的坐标
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
//X与Y坐标我们不用去变换,因为只考虑了Z坐标的变化
//coord[i][j][0] = j * disx - width / 2.0;
//coord[i][j][1] = i * disy - height / 2.0;
coord[i][j][2] = hzcoord[i][j] + vzoord[j][i];
}
}