Как написать функцию для сопоставления точек на холсте с точками на реальной плоскости - PullRequest
1 голос
/ 30 декабря 2011

Я пишу простой визуализатор Мандельброта на Python на экран пигмеев.Для каждого пикселя на экране 600 на 600 я строю график, находится ли этот пиксель (x, y) как комплексное число в множестве Мандельброта или нет.

Проблема в том, что я начинаю с(0, 0) и итерации до (600, 600), большинство из которых в любом случае находится за пределами набора.Поэтому я увеличил масштабный коэффициент, но я все еще строю график только в верхнем правом квадранте.Мне бы хотелось как-нибудь сделать так, чтобы мой сюжет всегда был сосредоточен вокруг 0 ​​+ 0i.

Я хотел бы найти какой-то способ сопоставить холст 600px ^ 2 с реальной плоскостью из [-2, 2] по оси X до [2, -2] по оси Y.Это будет означать, например, что комплексное число 0 + 0i будет отображаться на экране (300, 300).Таким образом, мой сюжет всегда будет в центре.

Ответы [ 3 ]

2 голосов
/ 30 декабря 2011

Вы хотите окно для ваших данных.Вы знаете, что это 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).

1 голос
/ 31 декабря 2011
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 () преобразует точку из исходного пространства в новое.

1 голос
/ 30 декабря 2011

По правде говоря, я бы выбрал более гибкий подход и написал бы ваш код, чтобы разрешить довольно произвольные отображения, но буквально выполнить то, что вы просите, вы можете попробовать:

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

и то же самое из y. Это обрабатывает каждый пиксель как точку в центре экранной пары, но отображает углов пикселей на (+ -2, + -2). Это наиболее «правильный» способ отобразить всю область просмотра на всю площадь в комплексной плоскости, но одним из недостатков этого является то, что вы никогда не будете рисовать некоторые важные числа, такие как 0, действительная линия или мнимая линия.

...