03.坐标系统

  • 学习人数 15K+
  • 适合有C语言基础人群学习
avatar
林耿亮

你好编程主讲老师

上一节中,我们使用circle函数绘制了一个圆心为(0, 0),半径为300的圆形。

#include <easyx.h>
#include <stdio.h>
int main()
{
    initgraph(800, 600);
    circle(0, 0, 300);  //  圆心为(0, 0) 半径为300的圆
    getchar();
    closegraph();
    return 0;
}

运行后,确实画了一个圆。但是,这个圆在窗体的左上角。这个圆的位置为什么会在左上角呢。接下来,我们来讨论EasyX中的坐标系统。

画圆

1. 直角坐标系

现在我们来复习一下初中、高中一直学习使用过的直角坐标系。

直角坐标系

直角坐标系由两个数轴正交组成。这两个数轴分别为X轴,Y轴。一般而言X轴的方向为从左向右,Y轴的方向为从下至上。而X轴与Y轴交汇的地方为两数轴的零点,也是坐标系的原点。

整个平面上的点,可以通过从该点在X轴的投影与该点在Y轴投影的组合表示。

例如,P点在x轴的投影为Px。

在x轴的投影

P点在Y轴的投影为Py。

在y轴的投影

那么P点可以表示为(Px, Py)。

(Px, Py)

原点为(x, y)中,x,y均为0的点,即(0, 0)。

2. 物理坐标与逻辑坐标

在EasyX中也使用直角坐标系,但是与上面讨论的坐标系略有不同。

EasyX中,有两种坐标系。

  1. 物理坐标
  2. 逻辑坐标

物理坐标

物理坐标:坐标原点在窗口的左上角,X轴的方向为从左向右,Y轴的方向为上到下,度量单位是像素。

物理坐标

逻辑坐标

逻辑坐标:坐标默认的原点在窗口的左上角,X轴的方向为从左向右,Y轴的方向为上到下,度量单位是点。

逻辑坐标

绘图使用的是逻辑坐标,而逻辑坐标的原点在窗口左上角。所以,我们之前看到的圆在窗口的左上角。

为什么圆在左上角

物理坐标与逻辑坐标的区别

  1. 物理坐标:描述窗体的坐标体系
  2. 逻辑坐标:用于绘图的坐标体系

物理坐标是用于描述窗体的坐标体系,度量单位为像素。坐标原点、坐标轴方向均不能修改

逻辑坐标是程序中用于绘图的坐标体系,度量单位是点。默认情况下,逻辑坐标与物理坐标是一一对应的,一个逻辑点等于一个物理像素。并且,可以以物理坐标为基准,修改逻辑坐标原点。同时,坐标轴方向也是允许更改的。

3. 切换逻辑坐标原点

既然绘图是使用逻辑坐标的。如果,我们将逻辑坐标原点移动到窗体中心来,那么根据逻辑坐标在(0, 0)点绘制的圆形也会出现在窗体中间。

把逻辑坐标的原点移动到窗体中间,应该怎样做呢?

首先,我们需要获得窗体中心点的物理坐标

窗体中心点的坐标为: (宽度/2, 高度/2)。

窗体中心点的坐标

接下来,我们使用setorigin函数。以物理坐标为基准,将逻辑坐标的原点设置为物理坐标上的(x, y)点。

setorigin

例如,窗体的大小为800 * 600。那么窗体中心的物理坐标为(400, 300)。我们使用setorigin函数将物理坐标(400, 300)作为逻辑坐标的原点。

setorigin(400, 300);

现在,逻辑坐标的原点被移动到物理坐标的(400, 300)点。

切换逻辑坐标原点

将这行代码添加在画圆之前,现在圆形出现在窗体中间了。

#include <easyx.h>
#include <stdio.h>
int main()
{
    initgraph(800, 600);
    setorigin(400, 300);    //  将逻辑坐标原点设置为物理坐标的(400, 300)  
    circle(0, 0, 300);      //  圆形为(0, 0) 半径为300的圆
    getchar();
    closegraph();
    return 0;
}

圆形出现在窗体中间

4. 翻转逻辑坐标

目前我们已经将逻辑坐标原点移动到了窗体中心。但是,逻辑坐标的Y轴依然是向下的。我们可以翻转Y轴,让其向上。

setaspectratio

setaspectratio(1, -1);

翻转逻辑坐标

#include <easyx.h>
#include <stdio.h>
int main()
{
    initgraph(800, 600);
    setorigin(400, 300);    //  将逻辑坐标原点设置为物理坐标的(400, 300)  
    setaspectratio(1, -1);  //  翻转Y轴
    circle(0, 0, 300);      //  圆形为(0, 0) 半径为300的圆
    getchar();
    closegraph();
    return 0;
}