如何在程序中画出实际大小为7CM半径的圆

关于使用CDC画图的问题:
我设置用0.1mm作为单位
void CCircleView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)  
{
pDC->SetMapMode( MM_LOMETRIC );
CView::OnPrepareDC(pDC, pInfo);
}

画一个7cm直径的正圆

void CCircleView::OnDraw(CDC* pDC)
{
CCircleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

pDC->Ellipse( 0,0,700,-700 );
}
但实际画出来的不是7cm,却是5.1cm,为什么会这样?


答:


首先介绍下用GetDeviceCaps函数得到的信息:


HORZSIZE = 25.4*HORZRES/72


HORZRES为水平方向的像素总数


LOGPIXELSX  逻辑像素(小字体为96,大字体为120)


屏幕为15.4寸的,长为33.2cm,宽为20.7cm


注意GDI函数中的700只是一个逻辑单位,如果要得到实际的尺寸还得转化成像素再转化实际的长度。


70mm(逻辑)------   70*(72/25.4=1280/452表示1mm有多少个像素)*(332/1280表示每个像素的实际宽度)


70mm(逻辑)=70*1280/452*332/1280=70*332/452=51.41(实际)


因为任何逻辑单位假定的分辨率为72DPI,所以HORZSIZE VERTSIZE只在这个假定的分辨率下得到逻辑长度而不是实际长度。




1366 768 - - - 482 271          1366/72*25.4 = 481.8944444444444


 800 600  ---282 212       800/72*25.4=282.2222222      其他也可以通过同样的公式得到


1024 768  --- 361 271


1280 720 ----452 254


1280 800 ---452 282


而LOGPIXELSX和LOGPIXELXY这两个量是系统为显示字体而搞的鬼,比如10磅(或者说成10点)的字体,由于1磅为1/72英寸,所以系统的DPI为96的话,则一个字应该占10/72*96=13个像素,而如果这个值为120的话,则一个字应该占10/72*120=16个像素。所以这两个量跟本问题无关。


所以70mm是假定分辨率为72DPI下的逻辑长度,任何逻辑坐标都要转成设备坐标即像素(为了显示)。72DPI表示1英寸有72个点(像素)。那么逻辑长度1mm有多少个点(像素)呢?1英寸有72个点,1英寸又有25.4mm,所以1mm就应该有72/25.4个点,即70mm就应该有70*(72/25.4)个像素。


我们知道HORZSIZE=25.4*HORZRES/72,所以72/25.4=HORZRES/HORSIZE(即水平方向上的像素总数/水平方向上在假定分辨率为72DPI下的逻辑总长度)=1280/452


而我们的屏幕是33.2cm宽,像素为1280个,所以每个像素的实际长度应为332/1280mm


所以70mm的逻辑长度转成实际的物理长度就应该为70*(72/25.4)*33.2/1280=70*(1280/452)*332/1280=70*332/452=51.41mm的实际物理长度。


所以要想画出真实的物理长度得进行一翻转换。


我们注意在70mm(逻辑长度)在转化的时候只用到了332和452这两个数字,即屏幕的物理长度和水平方向像素总量为1280时在假定分辨率72DPI下的逻辑总长度(即HORZSIZE的值,这个值会随分辨率不同而不同,但不会随LOGPIXELSX而变化),所以在编程序时得考虑这两个量,HORZSIZE可以通过GetDeviceCaps轻松获取,而屏幕的物理长度怎么获取呢?这个问题我也不知道,我是自己用直尺量的(过后在网上查了下电脑的屏幕是15.4寸的)所以这样的程序没有可移植性,正如Charles Petzold说的那样(如果程序需要实际的视频显示大小的该怎么办?也话最好的解决方法是用对话框让用户输入它们)


哎,真蛋疼,那就搞个对话框让他输吧?coding....


void CCircleDlg::OnButton1() 
{
 // TODO: Add your control notification handler code here
 UpdateData(TRUE);
 CDC *pDC=GetDC();
 pDC->SetMapMode( MM_LOMETRIC );
 int Horzsize=pDC->GetDeviceCaps(HORZSIZE);
 int Vertsize=pDC->GetDeviceCaps(VERTSIZE);
 if(m_Width!=0 && m_Height!=0)
  pDC->Ellipse(0,0,10*m_Radius*Horzsize/m_Width,0-10*m_Radius*Vertsize/m_Height);//由于是UINT类型注意第4个参数的写法,否则当无符号数处理

}





量一量,呵呵,果然是7cm,啊哈哈!~~~


最后说明下,我的显示分辨率为1280*800,屏幕为15.4寸,332mm*207mm


希望大家读了这篇文章能对图形基础知识有所了解,Charles Petzold第5章讲得真是一塌糊涂,看了一下午不知道他要说啥,哎,高手就是高手没办法。你们若有问题请留言。。。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值