Сегодня мы попробуем нарисовать т.н. RGB-куб — куб, каждая точка поверхности которого будет окрашена в цвет, яркость каждой из компонент которого (красной, зеленой и синей) равна соответствующей координате в трехмерном пространстве. Каждому из цветов отвечает ось координат (x — красный, y — зеленый, z — синий).
Для собственно рисования используем замечательную графическую библиотеку cairo, а именно ее python-версию, Pycairo.
Как известно, данная библиотека используется повсеместно на просторах всем известных проектов, таких как GIMP, Inkscape, Mozilla и многих других. Кроме всего прочего, она позволяет рисовать различные 2D-объекты (эллипсы, прямоугольники, точки и т.д.) и сохранять результаты в разные форматы (PNG, SVG, PDF и т.д.). Этим мы и воспользуемся.
Теперь относительно математического аппарата. Нам нужно уметь преобразовать реальные трехмерные координаты точек поверхности кубика в двухмерные (изометрическая проекция на экран). Это мы сможем сделать с помощью следующих формул:
x' = (x — z) * sin 60о = (x — z) * 0.866
y' = (x + z) * cos 60о — y = (x + z) * 0.5 — y,
где x,y,z — реальные координаты точек куба, x',y' — координаты точек на экране.
Основным объектом cairo является т.н. поверхность (surface). Они бывают разных типов (SVG, PNG, PDF...), но в целом работа с ними схожа. Именно с создания такой поверхности мы и начнем:
filename — это имя файла, связанного с данной поверхностью (сюда мы впоследствии запишем результаты своей работы). Width и Height — думаю, понятно.
Получим так называемый «контекст» данной поверхности. Именно в контексте мы позже будем «колдовать».
Cairo позволяет рисовать различные двухмерные фигуры, но в нашем примере нам пригодиться лишь точка (т.е прямоугольник шириной и высотой в один пиксель), нарисовать которую можно следующим образом:
Как параметр командной строки будем передавать имя файла, в который будет записан результат. Вторым параметром мы будем регулировать то, какую сторону кубика мы хотим увидеть (темную или светлую).
Вот, собственно текст:
Для его работы необходимо, чтобы был установлен pycairo (должен быть в репозиториях всех основных дистрибутивов, но можно скачать и с официального сайта).
А вот результаты:


Конечно, можно украсить данный пример, параметризировав габариты кубика, а также научиться его поворачивать под разными углами.
Для собственно рисования используем замечательную графическую библиотеку cairo, а именно ее python-версию, Pycairo.
Как известно, данная библиотека используется повсеместно на просторах всем известных проектов, таких как GIMP, Inkscape, Mozilla и многих других. Кроме всего прочего, она позволяет рисовать различные 2D-объекты (эллипсы, прямоугольники, точки и т.д.) и сохранять результаты в разные форматы (PNG, SVG, PDF и т.д.). Этим мы и воспользуемся.
Теперь относительно математического аппарата. Нам нужно уметь преобразовать реальные трехмерные координаты точек поверхности кубика в двухмерные (изометрическая проекция на экран). Это мы сможем сделать с помощью следующих формул:
x' = (x — z) * sin 60о = (x — z) * 0.866
y' = (x + z) * cos 60о — y = (x + z) * 0.5 — y,
где x,y,z — реальные координаты точек куба, x',y' — координаты точек на экране.
Основным объектом cairo является т.н. поверхность (surface). Они бывают разных типов (SVG, PNG, PDF...), но в целом работа с ними схожа. Именно с создания такой поверхности мы и начнем:
svg = cairo.SVGSurface(filename, Width, Height)
filename — это имя файла, связанного с данной поверхностью (сюда мы впоследствии запишем результаты своей работы). Width и Height — думаю, понятно.
Получим так называемый «контекст» данной поверхности. Именно в контексте мы позже будем «колдовать».
ctx = cairo.Context(svg)
Cairo позволяет рисовать различные двухмерные фигуры, но в нашем примере нам пригодиться лишь точка (т.е прямоугольник шириной и высотой в один пиксель), нарисовать которую можно следующим образом:
ctx.rectangle(x, y, width, height)
ctx.set_source_rgb(red,green,blue)
ctx.fill()
Как параметр командной строки будем передавать имя файла, в который будет записан результат. Вторым параметром мы будем регулировать то, какую сторону кубика мы хотим увидеть (темную или светлую).
Вот, собственно текст:
#!/usr/bin/env python
import cairo
import sys
class _2Dpoint:
def __init__(self, _x, _y, _z):
self.x = _x * 0.866 - _z * 0.866
self.y = _x * 0.5 + _z * 0.5 - _y
def draw_point(cntx, x, y, z):
point = _2Dpoint(x, y, z)
cntx.rectangle(x0 + point.x, y0 + point.y, 1, 1)
if dark:
red = float((max_ax - x) / max_ax)
green = float((max_ax - y) / max_ax)
blue = float((max_ax - z) / max_ax)
else:
red = float(x / max_ax)
green = float(y / max_ax)
blue = float(z / max_ax)
cntx.set_source_rgb(red,green,blue)
cntx.fill()
Width = 100
Height = 100
svg = cairo.SVGSurface(sys.argv[1], Width, Height)
if sys.argv[2]=='true':
dark = True
else:
dark = False
ctx = cairo.Context(svg)
x0 = Width / 2
y0 = Height / 2
max_ax = 50.0
# full red. red = 1
x = max_ax
for y in range(0, Height - y0):
for z in range(0, Width - x0):
draw_point(ctx, x, y, z)
# full green. green = 1
y = max_ax
for x in range(0, Height - y0):
for z in range(0, Width - x0):
draw_point(ctx, x, y, z)
# full blue. blue = 1
z = max_ax
for x in range(0, Height - y0):
for y in range(0, Width - x0):
draw_point(ctx, x, y, z)
svg.finish()
Для его работы необходимо, чтобы был установлен pycairo (должен быть в репозиториях всех основных дистрибутивов, но можно скачать и с официального сайта).
А вот результаты:
Конечно, можно украсить данный пример, параметризировав габариты кубика, а также научиться его поворачивать под разными углами.