有关逻辑坐标系统和备坐标系统的问题

cloudshadow1 2001-07-29 11:04:29
我执行以下语句:
pDC->SetMapMode(MM_TEXT);
pDC->SetViewportOrg(100,100);
RECT rect;
rect.left=rect.top=0;
rect.bottom=rect.right=200;
pDC->DPtoLP(&rect);
CString str;
str.Format("left=%d,right=%d,top=%d,bottom=%d",rect.left,rect.right,rect.top,rect.bottom);
MessageBox(str);
结果输出为left=-100,right=100,bottom=100,top=-100.
但我从上面的代码可以看出我设定的设备坐标系统的原点为(100,100),也就是说设备坐标系统的原点在逻辑坐标原点的右下角(100,100)点处。
这时当我执行pDC->DPtoLP(&rect);时函数应该将rect由设备坐标系统的坐标转为逻辑坐标系统的坐标,这样照我的推断结果应该为left=100,right=300,bottom=300,top=100.
为什么我的推断与实际结果不符呢?请指教。
...全文
240 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
lixiner 2001-08-03
  • 打赏
  • 举报
回复
逻辑坐标(Page space)和设备坐标(device space)的原点可以重合,也可以不重合,坐标轴的方向也可以不一样,但设备坐标x轴永远向右,y轴永远向下,变的只是逻辑坐标轴。

你贴得这句话是什么意思?好像是理解不对吧?
逻辑,设备坐标的原点和方向都可以设定
lz_0618 2001-08-03
  • 打赏
  • 举报
回复
只是一个假设而已,而且这种假设更符合字面意义,因为存在这样的事实:
1)
this->GetClientRect(rect);
pDC->SetMapMode(MM_ISOTROPIC);
pDC->SetWindowExt(500,500);
// ^^^^^^^
pDC->SetWindowOrg (0,0);//逻辑原点(0,0)
pDC->SetViewportExt(rect.right,-rect.bottom);
// ^^^^^^^^^^^^^^^^^^^^^^^
pDC->SetViewportOrg (rect.right/2,rect.bottom/2);
2)
this->GetClientRect(rect);
pDC->SetMapMode(MM_ISOTROPIC);
pDC->SetWindowExt(500,-500);
// ^^^^^^^
pDC->SetWindowOrg (0,0);//逻辑原点(0,0)
pDC->SetViewportExt(rect.right,rect.bottom);
// ^^^^^^^^^^^^^^^^^^^^^^^
pDC->SetViewportOrg (rect.right/2,rect.bottom/2);

不管原点坐标如何改变,输出图形是完全一样的,这也是我所说的逻辑坐标和物理坐标只有变换的意义。

lixiner(大汤姆狼) 朋友,不知对数据库熟不熟,今天遇到一个头疼的问题,居然找不到错误的原因,----“函数序列错误??”,折腾了一下午也不知为何出错,数据库的操作放在的一个从Listctrl继承下来的Grid中的按钮中,单击该按钮发送消息到View,弹出对话框,第一次运行正常,第二次单击就出现了上面的错误,以后凡是涉及数据库的操作全出上面的错误,真是怪事!!
数据库使用的是ODBC的CRecordset类。不知是不是和代码表有关系,我把好多代码全放在一个表里了,在该View中使用了两个该表得到的记录集的变量,只是过滤条件不同,在显示对话框时,将对应表的代码翻译(在表中循环查找)成名称并插入组合框,按确定时,再将名称翻译成(在表中循环查找)代码,再保存,不知问题是不是出在代码的翻译方面??遇到这种情况不知有没有更好的解决方法。
有时间请帮忙看看:http://www.csdn.net/expert/topic/222/222320.shtm
我的姓名:李忠 Email:LZ_0618@sina.com ,交个朋友如何

lz_0618 2001-08-02
  • 打赏
  • 举报
回复
从你上面的解释看,也不能证明你贴出的那段English能说明什么问题,我在一开始就指出所谓的坐标系只是用来进行坐标变换用的,根据某种映射关系,设备坐标的原点是永远映射到逻辑坐标的原点的,假如不是这样映射的坐标系是没有一点实际意义的。
当然,按满足这种影射关系的坐标,在逻辑或设备坐标下做图,绝对是做不出在两个位置的图形来的。
lixiner 2001-08-02
  • 打赏
  • 举报
回复
还有,我把全部过程再说一下,你可以在纸上画一下
看结果是否符合显示图形
1,pDC->SetMapMode(MM_ISOTROPIC或MM_ANISOTROPIC)
其他模式,设备和逻辑相互的比例,方向关系都已经规定死了
2,pDC->SetWindowExt(500,500);//逻辑区大小500,500方向y下,x右
pDC->SetViewportExt(rect.right,-rect.bottom);//设备区大小是客户区大小(588,318)方向y<0,上为正,x右
这两句设定逻辑和设备区的大小,和方向(也就是在逻辑上(500,500)的大小就是
设备区(588,318)的大小
在纸上分别画出逻辑和设备区
3,pDC->SetWindowOrg (0,0);//逻辑原点(0,0)
逻辑原点不变(也可以改变)
pDC->SetViewportOrg (rect.right/2,rect.bottom/2);//设备区原点(294,159)
设备的新原点放在原坐标的(294,159)
4,把逻辑圆画在逻辑坐标上
5,按照原点(新原点),方向对应的关系把逻辑圆映射到设备坐标
比较结果(注意现在设备原点是客户区的中心位置)
再换换参数,一定行的(di)! : )

lixiner 2001-08-02
  • 打赏
  • 举报
回复
Lz_0618:
情况是这样的,例子中
pDC->SetWindowOrg (0,0);//逻辑取缺省原点
pDC->SetViewportOrg (rect.right/2,rect.bottom/2);
把设备原点(0,0)放在客户区的中心
而显示时逻辑圆(0,0,250,250)的左上点也在客户区中心
我标的坐标是逻辑(0,0)对应设备原点变换前的坐标(294,159)
显示时确实是逻辑原点(0,0)对应现在的设备原点(0,0)《变换前的坐标(294,159)》
lz_0618 2001-08-01
  • 打赏
  • 举报
回复
to : lixiner(大汤姆狼):
要是按MFC的说明
请看mfc如下说明
The viewport origin marks the point in the device coordinate system to which GDI maps the window origin, a point in the logical coordinate system specified by the SetWindowOrg member function. GDI maps all other points by following the same process required to map the window origin to the viewport origin. For example, all points in a circle around the point at the window origin will be in a circle around the point at the viewport origin. Similarly, all points in a line that passes through the window origin will be in a line that passes through the viewport origin.

那逻辑点(0,0)应该对应设备点(0,0),事实好象不是这样,请解释一下?????
lixiner 2001-08-01
  • 打赏
  • 举报
回复
补充:由于设备,逻辑原点,方向映射对应
所以在逻辑的第一像限
也必然在设备的第一像限!
lixiner 2001-08-01
  • 打赏
  • 举报
回复
请看下例:void CMy1View::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
// TODO: Add your specialized code here and/or call the base class
CRect rect;
this->GetClientRect(rect);
pDC->SetMapMode(MM_ISOTROPIC);
pDC->SetWindowExt(500,500);//逻辑区大小500,500方向y下,x右
pDC->SetWindowOrg (0,0);//逻辑原点(0,0)
pDC->SetViewportExt(rect.right,-rect.bottom);//设备区大小是客户区大小(588,318)方向y<0,上为正,x右
pDC->SetViewportOrg (rect.right/2,rect.bottom/2);//设备区原点
(294,159)
CView::OnPrepareDC(pDC, pInfo);
}
void CMy1View::OnDraw(CDC* pDC)
{
CMy1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->Ellipse(CRect(0,0,250,250));//按照逻辑和设备坐标原点,方向对应映射,
圆显示在客户区右上方(第一像限)(逻辑x,y都为正)
}
如果改为pDC->SetViewportExt(rect.right,rect.bottom);//y>0 下为正
那么圆显示在客户区右下方(第一像限)(逻辑x,y都为正)
如再改pDC->Ellipse(CRect(0,0,-250,-250))
那么圆显示在客户区左上方(第四像限)(逻辑x,y都为负)
可以自己改变逻辑坐标方向,原点位置看看结果!
lixiner 2001-08-01
  • 打赏
  • 举报
回复
解释:我说的逻辑坐标和设备坐标原点相对应
不是指坐标相同而是指逻辑坐标原点通过映射后一定要和设备坐标原点重合
请看mfc如下说明
The viewport origin marks the point in the device coordinate system to which GDI maps the window origin, a point in the logical coordinate system specified by the SetWindowOrg member function. GDI maps all other points by following the same process required to map the window origin to the viewport origin. For example, all points in a circle around the point at the window origin will be in a circle around the point at the viewport origin. Similarly, all points in a line that passes through the window origin will be in a line that passes through the viewport origin.
另外,设备坐标大小,正方向的选择是通过函数virtual CSize SetViewportExt( int cx, int cy );规定,如果cx<0则左为正,cy<0则上为正方向
SetWindowExt 设置逻辑的大小和正方向.

lixiner 2001-07-31
  • 打赏
  • 举报
回复
对我不理不睬?对不对说个看法!
lz_0618 2001-07-31
  • 打赏
  • 举报
回复
to cloudshadow1(云影):
我认为,在MM_TEXT模式下,逻辑坐标(Page space)和设备坐标(device space)是重叠的。
用SetViewportOrg改变原点后物理设备坐标(physical device)和设备坐标(device space)是不同的。
对于你的问题:
1。p1(0,0),p2(200,200)我认为windows看作物理设备坐标(physical device);
2。当原点改到(100,100)后p1就对应设备坐标(device space)下的点(-100,-100)
3。因为在MM_TEXT模式下,逻辑坐标(Page space)和设备坐标(device space)是完全重叠的。所以逻辑坐标就是(-100,-100)。

在其他影射模式下,如MM_ISOTROPIC模式下,关系就很复杂了,逻辑坐标(Page space)和设备坐标(device space)的原点可以重合,也可以不重合,坐标轴的方向也可以不一样,但设备坐标x轴永远向右,y轴永远向下,变的只是逻辑坐标轴。
另外,只有在同时改变设备和逻辑坐标原点时,才会出现两坐标系原点不一致的情况。

//*************************************************************************
声明:以上只是我的理解,我没有看到有关资料能支持我的观点,有什么理解不对的地方,请各位高手批评指正!!!!!!!!!!!!!!!!!!
//*************************************************************************
cloudshadow1 2001-07-30
  • 打赏
  • 举报
回复
那么physical device的坐标原点跟device space的坐标原点有什么关系?
lz_0618 2001-07-29
  • 打赏
  • 举报
回复
按我的理解SetViewportOrg设置而产生的坐标系,只是作为变换用的,也就是说,DPtoLP函数需要的参数是物理上的设备坐标(原点(0,0)永远在左上角),这样就完全能解释输出结果的问题了。你可以参考一下我的帖子:
http://www.csdn.net/expert/topic/212/212856.shtm
lixiner 2001-07-29
  • 打赏
  • 举报
回复
更正:
对不起,手误!
应该是调用的函数!
lixiner 2001-07-29
  • 打赏
  • 举报
回复
补充说明:
参数只是数值!
是逻辑是设备坐标
关键看调用的参数
不只这种看法对不对!
lixiner 2001-07-29
  • 打赏
  • 举报
回复
设置中逻辑(0,0)对应设备(100,100)(逻辑设备原点相对应)
四个顶点坐标只是数值
rect->DPtoLP(&rect);你把它作为了设备值
设备的(0,0)自然对应逻辑的(-100,-100)
(200,200)对应(100,100)
lz_0618 2001-07-29
  • 打赏
  • 举报
回复
我说的设备坐标原点永远在窗口的左上角,是指的physical device的设备坐标原点,而用SetViewportOrg改变原点后的坐标系的原点是可变的,对应的是所谓的device space,而SetWindowOrgEx对应的是Page space,95/98不支持World space.
lixiner 2001-07-29
  • 打赏
  • 举报
回复
云影同志,不知你对我的解释有何看法?
cloudshadow1 2001-07-29
  • 打赏
  • 举报
回复
我看过了你的贴子,但有点牵强附会之意。
我认为设备坐标原点不是永远在窗口的左上角,从MSDN中得知SetViewportOrg()就是要来设定设备坐标的原点(其参数为相对于逻辑坐标原点),当然你说是这两面三刀下原点是用来变换坐标时用的,我一点也不反对,但这又能解释问题了吗?
shiyutao2010 2001-07-29
  • 打赏
  • 举报
回复
gz

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧