视口(View Port)与逻辑窗口(Logical Window)

一般我们直接在整个图形或者绘图窗口范围内绘图。但有时我们直接在图片的部分区域上进行绘制(并且以该区域的左上角为原点)会更加方便。我们可以使用视口(View port)来实现该功能。

在某些时候,我们需要缩放绘图,或者将原点设置到任意位置。这可以通过使用逻辑窗口(Logical window)来实现。

视口(View Port)

视口控制我们在图像画布(或者绘图窗口)的哪一部分上进行绘制。

下列程序在绘图窗口上绘制三个圆。注意它们在窗口中的位置。

from easygraphics import *

def main():
    init_graph(400, 300)
    circle(100, 100, 50)
    circle(100, 100, 100)
    circle(100, 100, 120)
    pause()
    close_graph()

easy_run(main)
../_images/08_without_view_port.png

下面的程序将视口设置到(100,50)和(300,250)之间,然后使用和前例完全相同的代码画了三个圆。比较一下两个程序的结果。注意我们预先在视口周围绘制了边线,以便更好的展现裁剪(clipping)的效果。

from easygraphics import *

def main():
    init_graph(400, 300)
    set_color("lightgray")
    draw_rect(100, 50, 300, 250)
    set_color("black")

    set_view_port(100, 50, 300, 250)
    circle(100, 100, 50)
    circle(100, 100, 100)
    circle(100, 100, 120)
    pause()
    close_graph()

easy_run(main)
../_images/08_with_clip.png

在上面的例子中,所有画到视口外的内容都被裁掉了。我们可以通过将“clip”参数设为False来关闭这个特性。

from easygraphics import *

def main():
    init_graph(400, 300)
    set_color("lightgray")
    draw_rect(100, 50, 300, 250)
    set_color("black")

    set_view_port(100, 50, 300, 250, clip=False)
    circle(100, 100, 50)
    circle(100, 100, 100)
    circle(100, 100, 120)
    pause()
    close_graph()

easy_run(main)
../_images/08_without_clip.png

逻辑窗口

在Easy Graphics(和其使用的Qt系统)中,实际上有两个坐标系,即**逻辑坐标系**和**物理坐标系**。

**物理坐标系**是实际在绘图设备(绘图窗口或者图像画布)上的坐标系。原点(0,0)永远位于设备的左上角,X轴正向朝右,Y轴正向向下。

**逻辑坐标系**是我们在绘图指明图形位置时所用的坐标。例如,我们执行circle(50,50,100)时,圆心(50,50)就是逻辑坐标。

Easygraphics在绘图时,会将逻辑坐标值转换为物理坐标值。在缺省状态下,逻辑坐标系和物理坐标系是重合的。而视口和逻辑窗口的设置会影响如何进行坐标转换。

Qt的文档 详细说明了坐标系转换的过程,请参阅。

下面的例子中,将逻辑原点移动到了绘图窗口的中心,并在x和y方向上同时对绘制的图像放大100倍

  • 说明1:我们设置的视口是600像素宽,400像素高;逻辑窗口的宽是6,高是4。因此,在x轴方向上我们得到了600/6=100倍放大;在y轴方向我们也得到了400/4=100倍放大。
  • 说明2:逻辑窗口的宽是6,高是4,并且我们把逻辑窗口的左上角放到了(-3,-2),因此(0,0)就到了窗口的正中。
from easygraphics import *

def main():
    init_graph(600, 400)
    set_window(-3, -2, 6, 4)

    circle(0, 0, 1.5)
    pause()
    close_graph()

easy_run(main)
../_images/08_window.png

注意: 显然逻辑窗口又难懂又难用。因此,在实际中更多用 几何变换(Transform) 来实现上面的功能。