SoRoMan

人若无名,便可专心练剑.

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  12 随笔 :: 1 文章 :: 41 评论 :: 0 Trackbacks

思考:计算机图形学中的左上像素填充约定(top-left filling convention for filling geometry)

我们知道目前显示器显示的原理,光栅化显示最小的单元是pixel(或者说精度为piexl),一个pixel所占的区域一般是个正方形,显示器上的画面就由一个或多个这样的小方格组成。如果以每个小方格为一个单元来制定屏幕坐标的话,问题就来了,因为方格本身有大小,不是一个严格意义上的"点"。

问题来源:屏幕坐标点的选取以及像素方格本身的大小
如果以方格中心点为基准制定坐标点(即对于任意一整数坐标点p(x,y),p必为某个像素方格的中心),以一个方格为跨度来制定屏幕坐标系的话。如图,屏幕上3X3的方格组成一个正方形的画面,如果按照方格中心点为基准制定坐标点,其区域屏幕坐标为(0,0,2,2)(注意:0,1,2都位于方格中心,其中,左上角坐标为(0,0),右下角坐标为(2,2)),而按照数学运算,其上下跨距就是2-0 = 2 pixels,左右跨距2-0 = 2 pixels,即总共包含2X2=4个方格.而实际画面中的跨距是3X3,即共包含9个方格(从最左上端到最右下端),问题来了,前后矛盾了。左上像素填充约定可以解决这个问题。

问题解决:左上像素填充约定
还是举刚才的例子,如果给定左上角坐标为(0,0),右下角坐标为(2,2)的矩形区域,叫显示设备去绘制的话,按照左上像素填充约定,在屏幕上填充的像素点将是:(0,0),(0,1),(1,0),(1,0)这个2X2区域,而非图中所示的3X3区域。反过来说图中所示的3X3区域要用坐标表示的话应该是(0,0,3,3)。简单来说,在左上像素填充约定下,要填充(x1,y1,x2,y2)(x1,y1,x2,y2为整数)的矩形,实际填充的区域会是(x1-0.5,y1-0.5,x2-0.5,y2-0.5),这个区域的左上角像素坐标为(x1,y1),右下角像素坐标为(x2-1,y2-1),即实际的填充区域会向左和向上各偏移0.5个像素。故称左上像素填充约定。

  0 1 2
   0 口口口
   1 口口口
   2 口口口

D3D, GDI, OpenGL等图形库使用左上填充约定的,如果接触过这些图形库,你可能会知道这个约定。还记得画一个全屏幕的矩形吧:DrawRectangle(0, 0, Screen_Width-1, Screen_Height-1)。

想法一:想到别的填充约定,比如右上,左下,右下等,这些不知道有哪些系统使用。

想法二:如果以像素方格的左上角为基准制定坐标点(即对于任意一整数坐标点p(x,y),p必为某个像素方格的左上角),情况怎么样?这时,给定(0,0,2,2),则填充时可以还会遇到一样的问题,填充(0,0),(0,1),(1,0),(1,0),(2,0),(2,1),(0,2),(1,2),(2,2),最后还是包含了3X3= 9个像素。

想法三:
to be continued...

posted on 2006-07-26 16:55 SoRoMan 阅读(2077) 评论(7)  编辑 收藏 引用

评论

# re: 思考:计算机图形学中的左上像素填充约定(top-left filling convention for filling geometry) 2006-07-26 17:50 mroske
原来还有这种约定。。。

在我的认识中一个坐标都是从 0 开始,而长度都是从 1 开始。(光栅)

int w = 3, h = 3;
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
SetPixel(x, y, 0xffffff);
}
}
代码说明 y = h - 1 和 x = w - 1。

如果一个坐标它的长度因该为1,那么 p1(0, 0) 到 p2(2, 0) 的长度应该为3。即 (0,0), (1,0), (2,0),如果直接 2 - 0 = 2,那这个得到只是坐标差距,并不是长度。 换成长度为 2 = w - 1, w = 3;

typedef struct tagRECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
其中 left 和 top 是左上角的 x, y 轴坐标. right 和 bottom 是右下角的 x, y 轴坐标。
在设置这样一个矩形范围的时候,往往右下角坐标是不包括在内的,也就是说右下角实际坐标为 right - 1, bottom -1,所以 right - left 是可以直接算出其长度的。


以上纯属个人瞎吹。。。。
  回复  更多评论
  

# re: 思考:计算机图形学中的左上像素填充约定(top-left filling convention for filling geometry) 2006-07-26 21:14 SoRoMan
to mroske:

如果一个坐标它的长度因该为1,那么 p1(0, 0) 到 p2(2, 0) 的长度应该为3。即 (0,0), (1,0), (2,0),如果直接 2 - 0 = 2,那这个得到只是坐标差距,并不是长度。
------------------------------------------
不知道你这里说的长度是什么意思?

在屏幕上的最小单位是一个像素,屏幕上的坐标是以以像素为单位的,所以坐标之间的差距就是多少个像素.

p1(0, 0) 到 p2(2, 0) 之间的差距为2,表明中间跨越2个像素.或者说长度为2个像素. 所以不能填充(0,0),(1,0),(2,0) 3个像素.我们可以作个实验,你调用一些图形库中的画线函数,画出p1(0, 0) 到 p2(2, 0)的直线,最后在屏幕上出现的应该是2个像素,而不是3个.  回复  更多评论
  

# re: 思考:计算机图形学中的左上像素填充约定(top-left filling convention for filling geometry) 2006-07-27 11:29 mroske
:) 我所指的所谓“长度”即一个像素的长度,如果有3个像素,那我可能说长度为3。不好意思,让你费解了。

之所以我所 2 - 0 = 2 是坐标差距,是因为“0”在长度中是无意义的(但存在)。。

“你调用一些图形库中的画线函数,画出p1(0, 0) 到 p2(2, 0)的直线,最后在屏幕上出现的应该是2个像素,而不是3个”
----- 或许你是对的。

但是我认为画线,它因该存在于一个矩形中,即任何的线都是一个矩形的对角线。不好意思我再引用我先前的回答:
“在设置这样一个矩形范围的时候,往往右下角坐标是不包括在内的,也就是说右下角实际坐标为 right - 1, bottom -1,所以 right - left 是可以直接算出其长度的。 ”
如果说 left = 0, top = 0, right = 2, bottom = 0,那么 right - left 应该等于 2,即长度为 2。 那么实际坐标有如下:(0,0), (1,0),不包括的坐标(2,0)。证明右下角坐标是不包括的。



谢谢你的实验,我去做了一下。
  回复  更多评论
  

# re: 思考:计算机图形学中的左上像素填充约定(top-left filling convention for filling geometry) 2006-07-27 11:40 mroske
“即任何的线都是一个矩形的对角线”并非任何的线,我指任何的直线。:)  回复  更多评论
  

# re: 思考:计算机图形学中的左上像素填充约定(top-left filling convention for filling geometry) 2006-07-27 12:06 SoRoMan

“在设置这样一个矩形范围的时候,往往右下角坐标是不包括在内的,也就是说右下角实际坐标为 right - 1, bottom -1,所以 right - left 是可以直接算出其长度的。 ”
--------------------
你说的这个是结论,至于原因,就是为什么在绘制的时候不去包括右下角(right, bottom),而去绘制(right - 1, bottom - 1)?正如我文中说的,是左上约定在起的作用。

简单概括一下就是:

在一般的坐标系里面,比如画一个矩形(0,0,2,2),会经过(2,2)这点。而在以像素为单位的屏幕坐标系里面,像素有大小,所以如果以其中心点为基准(坐标点),在绘制的时候,就会包含(right, bottom)这个像素的1/4部分,但是1个像素是最小单元,要么绘制,要么不绘制,所以,为了解决无法绘制1/4像素的问题,就统统向左向上移动1/2像素,绘制移动后的矩形区域,其大小(面积)不变,位置变了,新的矩形的右下角成了(right - 1, bottom - 1)。
  回复  更多评论
  

# re: 思考:计算机图形学中的左上像素填充约定(top-left filling convention for filling geometry) 2006-07-27 23:08 mroske
:) 为了不污染你的 blog,我把我的想法写在了我自己的 blog,
http://blog.programfan.com/article.asp?id=16886
上面连接正是。  回复  更多评论
  

# re: 思考:计算机图形学中的左上像素填充约定(top-left filling convention for filling geometry) 2006-11-29 13:11 asuna
介个吧, 你们说的都很高深, 我看的也不是很懂. 偶只知道, 在(0, 0, 2, 2)的坐标里面, 画矩形的话是8个格子, 但是填矩形的话是4个格子.
不过我觉得如果你愿意, 既然坐标都设置成了中心点了, 矩形当然也可以填成9个格子.
不过如果不是自己写坐标和写填充函数的话, ms默认的坐标设置是左上角的坐标.
既然是约定么,应该就只是告诉大家他是照这个约定来填的象素.我的理解就是这个约定里面画会比填在下面和右边个多一个象素.
cc...  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理