取自《Focus On 3D Terrain Programming》中的一段:
1 bool CTERRAIN::MakeTerrainFault( int iSize, int iIterations, int iMinDelta, int iMaxDelta, float fFilter ) 2 { 3 ...... 4 ............. 5 for( iCurrentIteration=0; iCurrentIteration<iIterations; iCurrentIteration++ ) 6 { 7 //calculate the height range (linear interpolation from iMaxDelta to iMinDelta) for this fault-pass 8 iHeight= iMaxDelta - ( ( iMaxDelta-iMinDelta )*iCurrentIteration )/iIterations; 9 10 //pick two points at random from the entire height map 11 iRandX1= rand( )%m_iSize; 12 iRandZ1= rand( )%m_iSize; 13 14 //check to make sure that the points are not the same 15 do 16 { 17 iRandX2= rand( )%m_iSize; 18 iRandZ2= rand( )%m_iSize; 19 } while ( iRandX2==iRandX1 && iRandZ2==iRandZ1 ); 20 21 22 //iDirX1, iDirZ1 is a vector going the same direction as the line 23 iDirX1= iRandX2-iRandX1; 24 iDirZ1= iRandZ2-iRandZ1; 25 26 for( z=0; z<m_iSize; z++ ) 27 { 28 for( x=0; x<m_iSize; x++ ) 29 { 30 //iDirX2, iDirZ2 is a vector from iRandX1, iRandZ1 to the current point (in the loop) 31 iDirX2= x-iRandX1; 32 iDirZ2= z-iRandZ1; 33 34 //if the result of ( iDirX2*iDirZ1 - iDirX1*iDirZ2 ) is "up" (above 0), 35 //then raise this point by iHeight 36 if( ( iDirX2*iDirZ1 - iDirX1*iDirZ2 )>0 ) 37 fTempBuffer[( z*m_iSize )+x]+= ( float )iHeight; 38 } 39 } 40 //erode terrain 41 FilterHeightField( fTempBuffer, fFilter ); 42 } 43 ....... 44 .............. 45 return true; 46 }
===================
代码的核心内容就是实现一个fault formation算法,算法是一个简单的数学模型,所以只要按照在纸上画个图就明白了。随笔的重点只是一行代码:
iDirX2*iDirZ1 - iDirX1*iDirZ2>0
这行代码参考的是二维向量共线定理:若设a=(x1,y1),b=(x2,y2),则有x1y2=x2y1。即与平行概念相同x1y2 - x2y1=0
另外,iMinDelta和iMaxDelta确实不符合我们的习惯,我们一般都习惯iMinValue和iMaxValue这样
时间: 2024-11-06 03:38:18