高程数据的色彩渲染+光照

成果效果见下图

在这里插入图片描述

颜色查找表的建立

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();

这里渲染的颜色是用圆点表达的而非方格。

猜你喜欢

转载自blog.csdn.net/llhllq2015/article/details/117623602
今日推荐