
正文
调色函数c语言 c++调色板
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
对这个C语言程序很感兴趣,但是不知道它的每个步骤是什么意思,求大虾解释。
// 我只是简单的看了一下,难免有错,请见谅。希望能帮助您,如果有问题请回复。
// 祝你学习顺利
# include stdio.h
# include stdlib.h
# include string.h
# include malloc.h
# include ctype.h
# include process.h
# include windows.h
// 上面这些是头文件,include之后可以使用其中定义的函数和变量,比如Include string.h之后就可以使用string这个类了。
int bitmapToGray(char *OriginalBMP,char *ResultBMP); //声明了一个函数将bitmap转换为灰度图像,括号里面的是输入的变量。这个相当于告诉编译器,后面会有一个函数叫这个名字,但没有具体定义函数内容。
int main() // 这个main函数是整个程序的入口,进入入口之后,程序会调用bitmapToGray这个函数。
{
bitmapToGray("C:\\Users\\Sky\\Desktop\\LONGJIANG.bmp",
"C:\\Users\\Sky\\Desktop\\LONGJIANG2.bmp");
return 0;
}
int bitmapToGray(char *OriginalBMP,char *ResultBMP) // 这里是bitmapToGray函数的具体定义,相当于把这个函数具体做什么一步一步写出来。
{
unsigned char *BMP24Image,*BMP8Image;
BITMAPFILEHEADER fh;
BITMAPINFOHEADER ih;
RGBQUAD Color[256];
BYTE CTemp[3]; //颜色分量
int Row,Col,nCol;
int i,j,k;
FILE *f,*p;
//上面的都是声明变量,这些变量的申请速度很快,因为他们在栈上,这个空间一般有1M,读写速度都比较快,使用起来安全。
BMP24Image=(unsigned char*)calloc(2000*2000,sizeof(unsigned char));
BMP8Image=(unsigned char*)calloc(1000*1000,sizeof(unsigned char));
//上面是申请空间,这个空间是在堆上面,这个堆基本就是内存,和虚拟内存了,很大,但是会比较慢,而且管理起来比较复杂。
if((f=fopen(OriginalBMP,"rb"))==NULL)
{
printf("open %s error,please check\n");
return 0;
}
fread(fh,sizeof(BITMAPFILEHEADER),1,f);
if(fh.bfType!='MB')
{
printf("This is not a BMP picture\n");
return 0;
}
fh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
+sizeof(RGBQUAD)*256;
fread(ih,sizeof(BITMAPINFOHEADER),1,f);
Row=ih.biHeight;
Col=ih.biWidth;
Col=Col/4*4;
nCol=Col*4/4*4; //扫描宽度
ih.biBitCount=8; //改变像素位数大小,8位,256色
fread(BMP24Image,sizeof(unsigned char),Row*Col,f);
// 上面就是读取BMP图像
for(i=0;iRow;i++)
{ for(j=0;jCol;j++)
{
if(BMP24Image[i*Col+j]128)
BMP8Image[i*Col+j]=255;
else BMP8Image[i*Col+j]=100;
// 上面是对BMP进行二值化处理
for(k=0;k3;k++)
{
CTemp[k]=BMP24Image[i*nCol+j*3+k];
}
BMP8Image[i*Col+j]=CTemp[2]*0.299+CTemp[1]*0.587+CTemp[0]*0.114;//转化公式
}
}
// 上面大概是空间转换YUV到RGB
fclose(f);
if((p=fopen(ResultBMP,"wb"))==NULL)
{
printf("open savefile error\n");
return 0;
}
// 准备进行写入操作
for(i=0;i256;i++) //调色板
{
Color[i].rgbBlue=i;
Color[i].rgbGreen=i;
Color[i].rgbRed=i;
Color[i].rgbReserved=0;
}
// 灰度图是从0~255,上面大概是进行灰度处理
fwrite(fh,sizeof(BITMAPFILEHEADER),1,p);
fwrite(ih,sizeof(BITMAPINFOHEADER),1,p);
fwrite(Color,sizeof(RGBQUAD),256,p);
fwrite(BMP8Image,sizeof(unsigned char),Row*Col,p);
fclose(p);
// 上面进行写入操作,并且关闭
return 0;
}
相关问答
Q1: c语言 allegro库 中的时钟怎么用? 求具体的例子~~~
基本的 PC 时钟只能是每秒触发 18.2 次, 这对于快节奏的动作游戏不是很适用. Allegro 可以用重新配置过的一个时钟例程来代替系统原来的,这个重编程过的时钟有 更高的触发频率,但是仍然以以前的速度调用 BIOS 处理程序. 你可以设置几个你自己 的虚拟时钟, 每个可以以不同的速度运行, Allegro 将不断的重编程时钟使它们在正 确的时间被调用.因为 Allegro 改变了 PIT 始终芯片的设置,它不能和 djgpp 的 libc 里的 uclock() 函数一起使用.
int install_timer();
加载 Allegro 时钟中断处理程序. 你必须在加载任何用户时钟例程之前,和在显示 鼠标,播放 FLI 动画或者 MIDI 音乐,使用其它的 GUI 例程之前执行它.
void remove_timer();
卸载 Allegro 时钟处理程序并且将时钟的控制权交还 BIOS. 你不必明显的调用它, 因为 allegro_exit() 将为你做这些.
int install_int(void (*proc)(), int speed);
加载用户始终处理程序, 参数 speed 的单位为万分之一秒.它和 install_int_ex(proc, MSEC_TO_TIMER(speed)) 作用相同.
int install_int_ex(void (*proc)(), int speed);
在用户时钟处理程序列表上加一个函数, 如果这个函数已经被加载,则调整它的速度. speed 的单位为硬件时钟单位, 即 1193181 分之一秒. 你可以利用以下的宏将其它 时间单位转换到这个单位上:
SECS_TO_TIMER(secs) - 给出两次触发间的秒数
MSEC_TO_TIMER(msec) - 给出两次触发间的万分之一秒数
BPS_TO_TIMER(bps) - 给出每秒触发多少次
BPM_TO_TIMER(bpm) - 给出每分钟触发多少次
如果没有空间再增加新的用户时钟程序, install_int_ex() 将返回一个负值, 否则返回零. 同时只能有 16 个时钟程序在使用,并且 Allegro 的其它部分 (GUI 代码, 鼠标显示例程, rest(), FLI 播放程序, 和 MIDI 播放程序) 需要加载它们自己的处理程序, 因此你要避免同时使用它过多.
你的函数将被 Allegro 中断处理程序调用而不是被处理器直接调用, 所以它能够 按正常的 C 函数来写而不需要特别的包装. 然而, 你必须知道,它将在一个中断中 被调用,而这给你希望在函数中做的事增加了许多约束.它不能使用大数量的堆栈, 不能调用任何 DOS 例程和使用调用了 DOS 例程的 C 库函数, 而且它必须被很快 的执行.不要在时钟处理程序里写太多的复杂代码: 一个基本的规则是你应该设置 一些标志然后在你的主控制循环里来回应它们.
在象 djgpp 这样的保护模式环境里, 内存被虚拟化并可以向磁盘交换. 由于 DOS 的不可重入, 如果磁盘交换发生在中断处理程序内部,系统将痛苦的死机, 所以你 需要确认你锁住了所有时钟例程中触及的所有内存 (包括代码和数据). Allegro 将锁住它用的所有东西,但是你有责任锁住你自己处理程序的. 宏 LOCK_VARIABLE (变量), END_OF_FUNCTION(函数名), 和 LOCK_FUNCTION(函数名) 可以被用来简化 这项任务.例如, 你想用一个中断处理程序来增加一个记数变量, 就应该这样写:
volatile int counter;
void my_timer_handler()
{
counter++;
}
END_OF_FUNCTION(my_timer_handler);
在你的初始化代码里,应该锁住内存:
LOCK_VARIABLE(counter);
LOCK_FUNCTION(my_timer_handler);
很明显,如果你使用了复杂的数据结构并且在这个处理程序中调用了其它的 函数,这就显得很笨拙,所以你应该使你的中断处理程序尽量简洁.
void remove_int(void (*proc)());
从用户中断例程列表中卸载一个函数.在程序的结束处, allegro_exit() 会自动运行它.
extern int i_love_bill;
如果被设为 TRUE, 打开专门的 'windows friendly' (对瘟都死友好) 时钟模式, 这将硬件时钟中断锁在 200 次每秒的速度,而不是对它动态重编程.这个模式减少 了时钟的精确性 (例如, rest() 将延时长度误差在 5 个百万分之一秒左右), 并且阻止了垂直回扫模拟器的工作 ( 在这个模式下对 timer_simulate_retrace() 的调用被忽略). 然而, 它带来的好处是, 使得 Allegro 程序可以工作在 windows 3.1 下, 而且使在 win95 的 DOS 模式下运行而没有出错信息. 这个标记应该在你加载始终模块前被设置, 而且在时钟在激活时不能改变它. 缺省状态下, allegro_init() 如果检测到 windows 的存在,将打开这个模式.
void timer_simulate_retrace(int enable);
时钟处理程序可以被用来模拟垂直回扫中断. 回扫中断在处理平滑动画时极其有用, 但不幸的是, VGA 硬件不支持它. EGA 可以,一些 SVGA 卡也可以,但这不够, 那些方法不够标准,来使其变的有用. Allegro 使这些运作起来依靠的是对时钟编程 使其成为一个普通的中断,当它认为下一次回扫将要发生时在中断处理程序里轮询 (polling) VGA 确认处于显示器刷新时的 sync(垂直回扫同步) 中. 这些在一些情 况下工作的非常好,但是它有一大堆限制:
- 在 SVGA 模式下不要在任何时候都用回扫模拟器. 它只能在某些芯片上用, 而在其它的芯片上不行, 并且它和所有的 VESA 实现程序有冲突. 回扫模拟器 仅仅在 VGA 13h 模式和 mode-X 下可信.
- 回扫模拟器不能工作在 win95 下, 因为 win95 在我试着从 PIT 里读取逝去的 时间时返回的是一些垃圾.如果有人知道我应该怎么做这些,请告诉我!
- 回扫模拟器在时钟处理程序里关掉了中断造成了许多的等待. 这将使你的整个系 统慢下来, 还可能在用 SB 1.0 声卡播放声音时造成无声 (因为它们不支持自动 初始化 DMA: SB 2.0 及以上版本没有问题).
由于要忍受这么多的问题, 我强烈建议你不要依赖于回扫模拟器. 如果你在 mode-X 下编程,而且不在乎你的程序能否在 win95 下使用, 它好极了 ,但交给用户一个可以 关掉它的开关却是个好主意.
回扫模拟器必须在你在 mode-X 下使用三缓冲函数时打开. 它也可以被用在简单的 回扫检测上, 因为轮询 vsync() 函数在声卡或时钟中断正好发生在回扫的同时时, 偶尔会丢失回扫. 当回扫中断模拟器打开, vsync() 将检查 retrace_count (回扫 计数器) 变量而不是轮询 VGA, 因此只有在它们被其它中断屏蔽时才会丢失回扫.
extern volatile int retrace_count;
如果回扫模拟器被加载,这个会随着每次垂直回扫而递增,否则它将每秒递增 70 次 (忽略回扫).这提供了一个避开加载用户时钟中断函数的麻烦而控制你的程序速度 的有效方法.
回扫变量的速度依赖于图形模式. 在 13h 模式 和 200/400 行的 mode-X 分辨率 下是每秒 70 次 回扫, 在 240/480 行模式下是 60 次. 它可以被慢到 50 次 (在 376x282 模式下) 也可能高到 92 次 (在 400x300 模式下).
extern void (*retrace_proc)();
如果回扫模拟器被加载, 这个函数将在每次垂直回扫时被调用, 否则将被每秒调用 70 次 (忽略回扫). 将其设置为 NULL 可以关掉回叫. 这个函数必须遵守和中断函 数相同的规则 (即, 它必须被锁住, 不能调用 DOS 或 libc 函数) 而且更甚的是: 它必须被 _非常_ 快的执行, 否则回对时钟同步造成混乱. 我能想到的唯一作用是 用来对调色板做一些巧妙的处理, 而三缓冲能够用 request_modex_scroll() 函数 来实现, 且 retrace_count 变量可以用来对你的代码记时. 如果你希望在 retrace_proc 里来改变调色板,则应该使用 inline _set_color() 函数而不是常 规的 set_color() 或 set_palette(), 而且你不要去尝试在一次回扫中改变二或 三个以上的调色板入口.
void rest(long time);
Allegro 一度接管了时钟, 基本的 delay() 函数将不能再工作,所以你必须使用这 个例程来代替. 时间的单位是百万分之一秒.
void rest_callback(long time, void (*callback)())
有点象 rest(), 不过它在等待所需的离开时间的同时将不停的调用指定的函数.
Q2: C语言 256色转灰度图。报错 error C2059: 语法错误:“类型”。代码是借鉴网上的,自己有一点改动。
调色函数c语言你用#define b定义了一个宏调色函数c语言,但没有定义它的展开代码。当预处理器对你的源码进行预处理时,会依次遇到如下的宏调用:
1、b+1;经处理后变成了+1;没有语法错误;
2、printf("%d\n",b);经处理后变成了printf("%d\n",);有语法错误,这就是问题所在。
可将#define b定义成#define b 100(或其它整数),来避免这个错误。
Q3: 求一个C语言图形变换程序,先进行图形绘制,后能进行图形复制、移动、缩放、旋转,跪求啦。。。
从这一部分开始,进入调色函数c语言了图形编程调色函数c语言的比较烦琐调色函数c语言的部分,要真正对图形编程有所了解,这一部分的内容是必须要掌握的。
在计算机绘图过程中,经常需要进行绘图变换,主要包括二维图形变换和三维图形变换。这一部分讨论二维图形变换,其内容有用户坐标到屏幕坐标的变换、图形的比例变换、对称变换、错切变换、旋转变换、平移变换和复合变换等。后面讲到了二维剪裁,即线段裁剪与多边形裁剪。
第一节 用户坐标到屏幕坐标变换
假设纸上有一个图形,要用计算机把它在屏幕上画出来。那么首先遇到的问题是,纸上的图形采用的坐标是实数域域中的直角坐标系或是极坐标系,统称为用户坐标系。而屏幕上采用的坐标系是整数域中直角坐标系,这类坐标系统称为设备坐标系。因此用户坐标系中图形需要经过变换才能绘制在屏幕上,显然这个变换的内容包括: 1)将用户坐标系中任意范围区域转换到屏幕某个范围区域,从而用户坐标系此范围区域内的图形也转换到屏幕上该范围区域内。 2)用户坐标系此区域内图形上的坐标值转换到屏幕上该范围区域内后不一定是整数,取整后才成为该范围区域内的屏幕坐标值。 3)用户坐标右手系到屏幕坐标左手系的坐标轴方向变换。 4)当屏幕坐标系水平方向与垂直方向刻度不等(即像素间距不等)时,为保持图形不走样,还要进行比例变换。下面介绍这些内容的具体计算问题。
1.窗口到视口的变换
更确切地说,是实际图形到屏幕图形的转换。有时也称为数据规格化。
在用户坐标系中,指定一矩形域以确定要显示(或绘制)的图形部分,这个矩形区域称为窗口。在屏幕上可任选一矩形域以显示(或绘制)窗口内的图形,该域称为视口。如图2-1所示。
一般视窗口的四条边界分别为:
左边界 x=x1、右边界 x=x2.下边界 y=y1,上边界y=y2。
视口的四条边界分别为:
左边界sx=sx1,右边界sx=sx2,上边界sy=sy1,下边界sy=sy2。
经变换后应有,窗口的上边界线段(或下边界线段)长x2-x1变换成视口上边界线段(或下边界线段)长sx2-sx1。设其比例变换因子为k1,则可得
k1*(x2-x1)=sx2-sx1
k1=(sx2-sx1)/(x2-x1)
对窗口内任一x坐标(x1=x=x2)变换后为视口内水平方向sx坐标(sx1=sx=sx2)。由上述有:
k1*(x-x1)=sx-sx1
sx=sx1+k1*(x-x1)
=sx1+(x-x1)*(sx2-sx1)/(x2-x1)
同样,经变换后窗口的左边界线段(或右边界线段)长y2-y1变换成视口左边界线段(或右边界线段)长sy2-sy1。设其比例变换因子为k2,则可得
k2*(y2-y1)=sy2-sy1
k2=(sy2-sy1)/(y2-y1)
对窗口内任一y坐标(y1=y=y2)变换后为视口内垂直sy坐标(sy1=sy=sy2),应有
k2*(y-y1)=sy-sy1
sy=sy1+k2*(y-y1)
=sy1+(y-y1)*(sy2-sy1)/(y2-y1)
于是对窗口内图形上任一点坐标(x,y)变换到屏幕上视口内成为(sx,sy),则
sx=sx1+(x-x1)*(sx2-sx1)/(x2-x1)
sy=sy1+(y-y1)*(sy2-sy1)/(y2-y1)
写成简式
sx=k1*x+a
sy=k2*y+b
这里
a=sx1-k1*x1
b-sy1-k2*y1
k1=(sx2-sx1)/(x2-x1)
k2=(sy2-sy1)/(y2-y1)
2. 实型值到整型值的变换
上面对窗口内图形上任一点坐标(x,y)变换到屏幕上视口内成为(sx,sy),
sx=k1*x+a
sy=k2*y+b k1,k2,a,b同上
这样计算出来的sx,sy一般是实型值,而屏幕上视口内屏幕坐标是整型值,因此要将sx,sy实型值转换成屏幕坐标系的整型值。这可以通过四舍五入的方法将实型值的绝对值圆整化。由于C语言中已经替调色函数c语言我们想到了这点,它提供的函数可以自动取整,因此用户在调用标准函数在屏幕上绘图时一般不需要考虑这个问题。当然也可以用赋值的类型转换规则来实现实型值到整型值的变换。
3. y坐标值方向变换
一般屏幕坐标系是直角左手系,y轴方向向下为正,原点在屏幕的左上角,如图2-2所示。
窗口内图形上任一点(x,y)变换到视口内成为(sx,xy),而(x,y)是相对用户坐标系(直角右手系)的。(sx,sy)是相对屏幕坐标系(直角左手系)的,因此y轴方向相反。为使窗口内图形变换到视口上图形其形状一致,需将视口上图形y轴方向变换成窗口内图形y轴方向。这只要将求得的视口内各点的sy整型坐标均用sy2去减,即sy2-sy(整型)代替sy(整型)即可,经这样的坐标轴方向变换后得到的视口内图形与窗口内图形一致。
4.长宽比例变换
屏幕坐标系x方向与y方向上的刻度可能不一样,这取决于水平方向像素间距与垂直方向偈素间距大小是否一致。如果两个方向的刻度不相等,那么用户坐标系下一个正方形将显示(或绘制)成为一个长方形有,一个圆将成为一个椭圆。
为保持原图形的长宽比。使图形显示(或绘制)后不走样,需求出屏幕上两侍标轴刻度的比值(即纵横比)。可以用函数getaspectratio()(见前文所述)返回x方向和y方向的比例数,从而求得这个比值。再瘵原图形y方向坐标乘以该比值,这样显示(或绘制)出来的图形应不走样。若不考虑图形的走样,就不必作这个变换。
第二节 二维几何变换
图形的几何变换一般是指对图形的几何信息经过变换后产生新的图形,图形几何变换既可以看作是坐标系不动而图形变动,变动后的图形在坐标系中的坐标值发生变化调色函数c语言;出可以看作图形不动而坐标系变动,变动后的图形在新坐标系下具有新的坐标值。这两种情况本质上都是一样的,都是图形由新的坐标值表示,因此是新产生的图形。图形几何变换包括比例变换、对称变换、错切变换、旋转变换、平移变换及其复合变换。图形上所有的点在几何变换前后的坐标关系一般用解析几何方法可以求得,但这些几何关系用矩阵方法表示,运算更为方便。
一、基本变换
图形基本几何变换是指比例变换、对称变换、错切变换、旋转变换和平移变换等。除平移变换外,这里其它四种几何变换都可以用组成图形的点向量(或称1×2阶矩阵)和2×2阶变换矩阵相乘表示,而平移变换需引入新方法来实现。
1、比例变换
设图形上一点P(x,y),经比例变换后成为新的菜上一点P'(x',y'),即有
x'=a*x
y'=d*y
式中a,d为比例因子
将此比例变换式写成矩阵式得
a 0
[x' y']=[x y] = [x y] * T
0 d
a 0
这里 T= 叫做比例变换矩阵。若a=d,则x,y坐标按同一比例变换。
0 d
当a=d1时,图形放大;当0a=d1时,图形缩小。
若a≠d,则x,y坐标按各自不同比例变换。
3 0
例 1: 设有比例变换矩阵 T= , 三角形abc经过比例变换成为三角形a'b'c'。
0 1
如图2-3所示。
3 0
a [1 2] = [3 2] a'
0 1
3 0
b [2 2] = [6 2] b'
0 1
3 0
c [2 3] = [6 3] c'
0 1
2. 对称变换
图形上一点P(x,y)经关于原点对称变换后成为新图形上一点P'(x',y'),则
x' = -x
y' = -y
写成矩阵形式成为
-1 0
[x' y'] = [x y] = [x y] * T
0 -1
-1 0
这里 T = 为关于原点对称变换矩阵。
0 -1
若关于x轴对称,则对称变换的矩阵表示为
1 0
[x' y'] = [x y] = [x y] * T
0 -1
1 0
于是关于x轴对称变换矩阵 T =
0 -1
若关于y轴对称,则对称变换的矩阵表示为
-1 0
[x' y'] = [x y] = [x y] * T
0 1
-1 0
于是关于y轴对称变换矩阵 T =
0 1
若关于直线y = -x对称,则对称变换矩阵表示为
0 -1
[x' y'] = [x y] = [x y] * T
-1 0
0 1
于是关于直线 y = x对称变换矩阵 T =
1 0
各种对称变换的图形均可由实例程序绘出,参见实例程序图形。
3. 错切变换
对图形的任一点P(x,y),作线性变换如下
x' = x + by
y' = y + dx
式中b,d为不全为零的常 数,点P'(x',y')为新图形上相应的点,这个变换称为图形的错切变换。
错切变换的矩阵表示为
1 d
[x' y'] = [x y] = [x y] * T
b 1
1 d
T = 叫做错切变换矩阵(b,d不全为零)。
b 1
① 当d=0时,x'=x+by,y'=y,这时图形的y坐标不变,x坐标值随(x,y)及系数b作线性变化。若b0时,图形沿x轴作错切位移;若b0,图形沿x轴负向作错切位移。
② 当b=0时,x'=x,y'=dx+y,此时图形的x坐标不变y坐标随(x,y)及系数d作线性变化。如d0,图形沿y轴正向作错切位移;如d0,图形沿y轴负向作错切位移。
③ 当b≠0且d≠0时,x'=x+by,y'=y+dx,图形沿x,y两个方向作错切位移。
1 2
例 2: 设有错切变换 矩阵 T = ,正方形abcd经此错切变换成为四边形a'b'c'd',
0 1
如图2-4所示。
1 2
a [0 0] = [0 0] a'
0 1
1 2
b [1 0] = [1 2] b'
0 1
1 2
c [1 1] = [1 3] c'
0 1
1 2
d [0 1] = [0 1] d'
0 1
4. 旋转变换
设图形上一点P(x,y)绕原点逆时针旋转θ角后成为新的图形上一点P'(x',y'),则由解析几何方法可得
x' = xcosθ + ysinθ
y' = -xsinθ + ycosθ
用矩阵表示为
cosθ -sinθ
[x' y'] = [x y] = [x y] * T
sinθ cosθ
cosθ -sinθ
这里 T = 为绕原点逆时针变换矩阵。若顺时针旋转时,θ角为负值。
sinθ cosθ
5. 平移变换
若图形上一点P(x,y)沿x轴平移 l距离,沿y轴平移m距离后成为新的图形上一点P'(x',y'),则有
x' = x + l
y' = y + m
式中l,m不全为零,这称为平移变换。但此变换无法用组成图形的点向量和2×2阶变换矩阵相乘来实现。
用二维点向量和2×2阶矩阵相乘不能表示图形的平移变换,那么自然会想到用三维点向量和3×3阶矩阵相乘来实现图形的平移变换。因此对图形上二个坐标的点向量需要添加一个坐标,使之成为三维点向量以便与三阶矩阵相乘,进而实现用矩阵表示平移变换。实际上就是对上面的二个坐标变换式添加第三个坐标变换式,即成为
x' = x + l
y' = y + m
k = k
这第三个坐标变换式(即k=k)必须是恒等式,因为不需作变换,本质上是为了进行矩阵运算而引入的。
将此三个变换式(仍然是图形的平移变换,不妨将k = k取成1=1)写成矩阵得
1 0 0
[x' y' l] = [x y l] 0 1 0 = [x y 1] * T
l m 1
1 0 0
显然 T = 0 1 0 为图形的平移变换矩阵。
l m 1
这里通过对原图形上二维点向量引进第三个坐标成为三维点向量,从而使原图形的平移变换 能用矩阵表示。同样其它基本变换也可以如此用矩阵表示。因此图形的基本变换都可以在这样的三维点向量下统一、整齐用矩阵表示。这样的三维点向量称为齐次点向量,也叫三维齐次坐标点,简称三维齐次坐标。只有在三维齐次坐标下,二维几何变换才都可以用矩阵表示。下面再进一步讨论一下齐次坐标的优点。
引用齐次坐标后,可将上面各种基本变换矩阵统一在一个三阶矩阵中。即
a b 0
T = c d 0
l m 1
式中左上角二阶矩阵实现比例、对称、错切、旋转等变换,左下角1×2阶矩阵实现平移变换,其中a,b,c,d,l,m只要赋以相应的值,并建立图形上点的齐次坐标(即在图形上点的坐标后引入第三个坐标1),这样就可以用图形上点的三维齐次坐标与此三阶矩阵相乘来表示三维图形的基本几何变换了。而变换后,不用考虑第三个坐标1,前面两个坐标就反映了图形的整个变换情况。
用齐次坐标表示一个图形上的点,可以有多种表示,如(6,8,1)、(12,16,2)、(30,40,5)等均表示图形上同一个点(6,8)。这样,齐次坐标可以表示计算机无法容纳的数。例如当计算机的字长为16位时,它能表示的最大整数为216-1=32767。若点坐标为(80 000,40 000),则计算机无法表示。但用齐次坐标可表示为(20 000,10 000,1/4),经过处理后再用第三个坐标支除前面两个坐标,从而得到原来通常的坐标。
齐次坐标优点很多,在计算机绘图中都采用这种表示来处理图形。下面介绍的图形复合几何变换就是如此。
二、复合变换
图形的复合几何变换是指图形作一次以上的基本几何变换,变换结果是每次基本变换矩阵的乘积。图殂的复合几何变换简称复合变换。
1. 复合平移
若对图形首先作平移变换 T1,然后再作平移变换T2,相应的平移变换矩阵分别为
1 0 0
T1 = 0 1 0
l1 m1 1
1 0 0
T2 = 0 1 0
l2 m2 1
则变换结果为复合平移变换T,其复合平移变换矩阵为
T = T1 * T2
1 0 0 1 0 0
= 0 1 0 * 0 1 0
l1 m1 1 l2 m2 1
1 0 0
= 0 1 0
l1+l2 m1|m2 1
调色函数c语言的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于c++调色板、调色函数c语言的信息别忘了在本站进行查找喔。





