1

我正在用 Python 在 pygame 屏幕上编写一个简单的 Mandelbrot 可视化器。对于 600 x 600 屏幕上的每个像素,我正在绘制这个像素 (x, y) 作为复数是否在 Mandelbrot 集中。

问题是我从 (0, 0) 开始并迭代到 (600, 600),其中大部分都在集合之外。所以我加入一个比例因子来放大,但我仍然只绘制右上象限。我想要一些方法,所以我的情节总是以 0+0i 为中心。

我想做的是找到某种方法将 600px^2 画布映射到从 x 轴上的 [-2, 2] 到 y 轴上的 [2, -2] 的真实平面。例如,这意味着复数 0+0i 将映射到屏幕上的 (300, 300)。这样,我的情节将始终居中。

4

3 回答 3

2

您需要一个数据窗口。你知道它有 600 像素宽和 600 像素高。像素坐标为 (0, 0) - (600, 600)。你可以这样做:

Point coordFromPixelLocation (pixelX, pixelY, pixelWidth, pixelHeight, minCoordX, maxCoordX, minCoordY, maxCoordY)
{
    xPercent = pixelX / pixelWidth;
    yPercent = pixelY / pixelHeight;

    newX = minCoordX + (maxCoordX - minCoordX) * xPercent;
    newY = minCoordY + (maxCoordY - minCoordY) * yPercent;

    return Point (newX, newY);
}

pixelX 和 pixelY 是要转换为较小范围的像素坐标。pixelWidth 和 height 是窗口的宽度和高度。min/maxCoordX/Y 是 (-2,-2) 到 (2,2) 的值。

于 2011-12-30T19:52:22.977 回答
1

实际上,我会采取更灵活的方法,并编写代码以允许相当任意的映射,但要按照您的要求进行操作,您可以尝试:

x = (float(pix_x) + 0.5 - 300.0) / 150.0

然后同样的y。这将每个像素视为屏幕对中心的一个点,但将像素的映射到 (+-2, +-2)。这是将整个视口映射到复平面中整个正方形的最“正确”方法,但这样做的一个缺点是您永远不会绘制一些重要的数字,例如 0、实线或虚线。

于 2011-12-30T19:58:47.640 回答
1
class Mapper:
    def __init__(self, old_ul, old_lr, new_ul, new_lr):
        self.old_ul = old_ul
        self.old_lr = old_lr
        self.new_ul = new_ul
        self.new_lr = new_lr
        self.old_diff = Point(old_lr.x - old_ul.x,
                              old_ul.y - old_lr.y)
        self.new_diff = Point(new_lr.x - new_ul.x,
                              new_ul.y - new_lr.y)

    def map(self, pt):
        nx = (self.old_lr.x+pt.x) * (self.new_diff.x / self.old_diff.x) + self.new_ul.x
        ny = (self.old_ul.y+pt.y) * (self.new_diff.y / self.old_diff.y) + self.new_lr.y
        return Point(nx, ny)
def main(args):
    pixelToReal = Mapper(Point(0, 0), Point(600, 600), Point(-2, 2), Point(2, -2))
    realToPixel = Mapper(Point(-2, 2), Point(2, -2), Point(0, 0), Point(600, 600))
    print(pixelToReal.map(Point(300,300))) # prints 0.0,0.0
    print(realToPixel.map(pixelToReal.map(Point(300,300)))) # prints 300,300
    for x in range(0,630, 30):
        for y in range(0,630, 30):
            print(pixelToReal.map(Point(x,y)))

Mapper 的构造函数取原来的左上角和右下角,以及新的左上角和右下角。Mapper.map() 将一个点从原始空间转换为新空间。

于 2011-12-30T21:16:09.207 回答