高程數(shù)據(jù)高程渲染+光照效果
- 成果效果見下圖
- 顏色查找表的建立
- 光照和透明度設(shè)置
- 色彩渲染視圖
成果效果見下圖
顏色查找表的建立
void CColortable::InitColorTable()
{
F_RGB blue(17, 60, 235);//藍色
F_RGB green(17, 235, 86);//綠色
vector<F_RGB> RGBList(60);
Gradient(blue, green, RGBList);
for (int i = 0; i < 60; i++)
{
tableRGB[i] = RGBList[i];
}
F_RGB yellow(235, 173, 17);//黃色
RGBList.clear();
RGBList.resize(60);
Gradient(green, yellow, RGBList);
for (int i = 0; i < 60; i++)
{tableRGB[i + 60] = RGBList[i];
}F_RGB red(235, 60, 17);//紅色
RGBList.clear();
RGBList.resize(60);
Gradient(yellow, red, RGBList);
for (int i = 0; i < 60; i++)
{tableRGB[i + 120] = RGBList[i];
}F_RGB white(235, 17, 235);//紫色
RGBList.clear();
RGBList.resize(76);
Gradient(red, white, RGBList);
for (int i = 0; i < 76; i++)
{tableRGB[i + 180] = RGBList[i];
}
}
//根據(jù)高程選顏色
inline int GetColorIndex(float z, float min_z, float max_z)
{
int temp = floor((z - min_z) * 255 / (max_z - min_z) + 0.6);
return temp;
}
// a b c
// d e f
// g h i
double CColortable::CalHillshade(float *tmpBuf, double Zenith_rad, double Azimuth_rad, double dx, double dy, double z_factor)
{
double dzdx = ((tmpBuf[2] + 2 * tmpBuf[5] + tmpBuf[8]) - (tmpBuf[0] + 2 * tmpBuf[3] + tmpBuf[6])) / (8 * dx);
double dzdy = ((tmpBuf[6] + 2 * tmpBuf[7] + tmpBuf[8]) - (tmpBuf[0] + 2 * tmpBuf[1] + tmpBuf[2])) / (8 * dy);
double Slope_rad = atan(z_factor * sqrt(dzdx*dzdx + dzdy*dzdy));
double Aspect_rad = 0;
if (abs(dzdx) > 1e-9)
{Aspect_rad = atan2(dzdy, -dzdx);if (Aspect_rad < 0){Aspect_rad = 2 * PI + Aspect_rad;}
}
else
{if (dzdy > 0){Aspect_rad = PI / 2;}else if (dzdy < 0){Aspect_rad = 2 * PI - PI / 2;}else{Aspect_rad = Aspect_rad;}
}double Hillshade = 255.0 * ((cos(Zenith_rad) * cos(Slope_rad)) + (sin(Zenith_rad) * sin(Slope_rad) * cos(Azimuth_rad - Aspect_rad)));
return Hillshade;
}
光照和透明度設(shè)置
COLORREF* CColortable::CreadColor(XYZ& xyz)
{
InitColorTable();//申請bufsize_t dstBufNum = (size_t)xyz.nRow * xyz.nCol * dstBand;
COLORREF *dstBuf = new COLORREF[dstBufNum];
//memset(dstBuf, 0, dstBufNum * sizeof(GByte));//設(shè)置方向:平行光
double solarAltitude = 45.0;
double solarAzimuth = 315.0;//
double Zenith_rad = osg::DegreesToRadians(90 - solarAltitude);
double Azimuth_math = 360.0 - solarAzimuth + 90;
if (Azimuth_math >= 360.0)
{Azimuth_math = Azimuth_math - 360.0;
}
double Azimuth_rad = osg::DegreesToRadians(Azimuth_math);//a b c
//d e f
//g h i
double z_factor = 2;
double alpha = 0.3; //A不透明度 α*A+(1-α)*Bfor (int yi = 1; yi < xyz.nRow - 1; yi++)
{for (int xi = 1; xi < xyz.nCol - 1; xi++){size_t e = (size_t)xyz.nCol * yi + xi;size_t f = e + 1;size_t d = e - 1;size_t b = e - xyz.nCol;size_t c = b + 1;size_t a = b - 1;size_t h = e + xyz.nCol;size_t i = h + 1;size_t g = h - 1;float tmpBuf[9] = { xyz.ptz[a], xyz.ptz[b], xyz.ptz[c], xyz.ptz[d], xyz.ptz[e], xyz.ptz[f], xyz.ptz[g],xyz.ptz[h], xyz.ptz[i] };double Hillshade = CalHillshade(tmpBuf, Zenith_rad, Azimuth_rad, xyz.fDx, -xyz.fDy, z_factor);GByte value = (GByte)((std::min)((std::max)(Hillshade, 0.0), 255.0));int index = GetColorIndex(xyz.ptz[e], xyz.zmin, xyz.zmax);GByte rgb[3] = { (GByte)tableRGB[index].R, (GByte)tableRGB[index].G, (GByte)tableRGB[index].B };size_t n;double v = value * alpha + (1 - alpha) * rgb[0];double v1 = value * alpha + (1 - alpha) * rgb[1];double v2 = value * alpha + (1 - alpha) * rgb[2];dstBuf[n] = RGB((std::min)((std::max)(v, 0.0), 255.0), (std::min)((std::max)(v1, 0.0), 255.0), (std::min)((std::max)(v2, 0.0), 255.0));}
}return dstBuf;
}
色彩渲染視圖
cl = clx[xyz.nCol * 1 * i + 1 * j]; ///查找生成的色彩值開始繪制*p = cl; CPen pen(PS_SOLID, 1, cl);CBrush brush(cl);CBrush *oldbr = pDC->SelectObject(&brush);CPen * oldpen = pDC->SelectObject(&pen);pDC->Rectangle(X - r, Y - r, X + r, Y + r);pDC->SelectObject(oldbr);pDC->SelectObject(oldpen);pen.DeleteObject();brush.DeleteObject();
這里渲染的顏色是用圓點表達的而非方格。
總結(jié)
以上是生活随笔為你收集整理的高程数据的色彩渲染+光照的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。