成果效果见下图
颜色查找表的建立
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];
}
}
//根据高程选颜色
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;
}
光照和透明度设置
COLORREF* CColortable::CreadColor(XYZ& xyz)
{
InitColorTable();
//申请buf
size_t dstBufNum = (size_t)xyz.nRow * xyz.nCol * dstBand;
COLORREF *dstBuf = new COLORREF[dstBufNum];
//memset(dstBuf, 0, dstBufNum * sizeof(GByte));
//设置方向:平行光
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-α)*B
for (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();
这里渲染的颜色是用圆点表达的而非方格。