else if (b <= a && b <= c) return b; else return c; }
//RGB颜色模型转换为HSV颜色模型
void CReality::RGBtoHSV(double r, double g, double b, double *h, double *s, double *v)
{
double m = Max(r,g,b); double n = Min(r,g,b); *v = m; if (m != 0) *s = (m - n) / m; else *s = 0; if (*s == 0) h = NULL;//饱和度为0,h无定义 else { double d = m - n; if (r == m) *h = (g - b) / d; else if (g == m) *h = 2 + (b - r) / d; else if (b == m) *h = 4 + (r - g) / d; *h = *h * 60; if (*h < 0) *h = *h + 360; } }
//HSV颜色模型转换为RGB颜色模型,如果可以转换返回true,否则返回false BOOL CReality::HSVtoRGB(double h, double s, double v, double *r, double *g, double *b)
{
if (s == 0) { if (h == NULL) *r = *g = *b = v; else //饱和度为0,色彩有定义,无法转换
return false; } else { if (h == 360) h = 0; h = h / 60; int i = (int)h; double f = h - i; double m = v * (1 - s); double n = v * (1 - s * f); double k = v * (1 - (s * (1-f))); switch (i) { case 0: *r = v;*g = k;*b = m;break; case 1: *r = n;*g = v;*b = m;break; case 2: *r = m;*g = v;*b = k;break; case 3: *r = m;*g = n;*b = v;break; case 4: *r = k;*g = m;*b = v;break; case 5: *r = v;*g = m;*b = n;break; default: break; } }
return true; }
//RGB颜色模型转换为HSL颜色模型
void CReality::RGBtoHSL(double r, double g, double b, double *h, double *s, double *L)
{
double m = Max(r,g,b); double n = Min(r,g,b); *L = (m + n) / 2; if (m == n) { *s = 0;h = NULL; } else {
if (*L <= 0.5) *s = (m - n) / (m + n); else *s = (m - n) / (2 - m - n); double d = m - n; if (r == m) *h = (g - b) / d; else if (g == m) *h = 2 + (b - r) / d; else if (b == m) *h = 4 + (r - g) / d; *h = *h * 60; if (*h < 0) *h = *h + 360; } }
//HSL颜色模型转换为RGB颜色模型,如果可以转换返回true,否则返回false BOOL CReality::HSLtoRGB(double h, double s, double L, double *r, double *g, double *b)
{
double m,n; if (L <= 0.5) n = L * (1 + s); else n = L + s - L * s; m = 2 * L - n; if (s == 0) { if (h == NULL) *r = *g = *b = L; else return false; } else { *r = RGBValue(m,n,h+120); *g = RGBValue(m,n,h); *b = RGBValue(m,n,h-120); }
return true; }
//根据传入的参数值计算RGB分量
double CReality::RGBValue(double m, double n, double hue) {
double r; if (hue > 360) hue = hue - 360; if (hue < 0) hue = hue + 360; if (hue > 60) r = m + (n - m) * hue / 60; else if (hue < 180) r = n;
else if (hue < 240) r = m + (n - m) * (240 - hue) / 60; else r = m; return r; }
以上就可以完成颜色模型相互之间的转换。其中当HSV颜色模型或HSL颜色模型转换为RGB颜色模型时,得到的三原色分量值处于0和1之间,只需再乘以255就可以使用MFC中RGB函数获得颜色值。
9.4 多边形网格明暗处理的实现
观察我们在第二节中汇制的真实感图形,会发现有明显的网格感,这是因为在绘制的时候,将剖分得到的三角面片上的每一点都按相同的光照进行处理,所以造成了光照的突变。为了解决这个问题,可以有以下几种方法。一是增加景物表面三角剖分得到的三角面片的数量,剖分得到的三角面片越小,其相邻三角面片之间的亮度突变越小。二是采用图像的方法,对得到的真实感图形进行平滑,来减小真实感图形中颜色的突变。三是对三角剖分得到的三角面片进行明暗处理,不再让整个三角面片使用相同的亮度。第三种方法可以使用Phong着色方法(法向量插值明暗法)来实现。
Phong着色方法的基本思想是:求得多边形网格顶点处的法向量,然后通过对法向量进行插值的方法求得多边形边上各点及多边形面内任意点处的法向量,最后根据求得的法向量计算多边形中每点处的实际亮度。对多边形进行法向量插值可以和第三章中介绍的多边形填充扫描转换算法相结合。用一条扫描线扫描多边形网格,在每条扫描线上计算法向量。该方法的基本步骤如下:
(1) 计算多边形的单位法向量
(2) 计算多边形顶点的单位法向量,该法向量可以是共享该顶点的所有多边形法向量的平均值。
(3) 按扫描线转换算法对多边形顶点的法向量进行双线性插值,计算出多边形内部(扫描线上位于多边形内部)各点的法向量,如图9.13所示。
NA由N1和N2线性插值得到:
NA?yA?y2y?yAN1?1N2
y1?y2y1?y2类似地,有:
NB?yB?y3y?yBN1?1N3
y1?y3y1?y3xB?xx?xANA?NB x1?x2xB?xANP?可以采用下面的增量方法来提高计算速度。
当扫描线y增加一个单位,变为y+1时,NA、NB的增量分别为:
?NA?1?N1?N2?,?NB?1?N1?N3?
y1?y2y1?y3当x增加一个单位(P点沿扫描线右移一个单位)时,NP的增量为:
?NP?1?NB?NA?
xB?xA现在来看一下如何实现Phong着色方法绘制真实感图形。修改Point3D结构: //三维空间中点 struct Point3D{ double x; double y; double z;
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库使用MFC实现真实感图形绘制(6)在线全文阅读。
相关推荐: