光栅图形学(3)配套Python画图代码

Note

本文为 从零学习软渲(3)-Bresenham画线算法 数学插图的配图代码

 

# -- coding: utf-8 --
from matplotlib.patches import Circle
import matplotlib.pyplot as plt
import numpy as np
from Point import Point


def f(x):
    return 0.7 * x + 0.15


def draw_annotate(point, tpoint, label, arrow=None):
    if arrow is None:
        plt.annotate(s='{0}'.format(label), xy=(point[0], point[1]), xytext=(tpoint[0], tpoint[1]), fontsize=14)
    else:
        plt.annotate(s='{0}'.format(label), xy=(point[0], point[1]), xytext=(tpoint[0], tpoint[1]), fontsize=14,
                     arrowprops={'arrowstyle': '->'})


def draw_piont_with_annotate(point, tpoint=None, psize=None, label='', legend=None, arrow=None):
    plt.scatter(point.x, point.y, s=psize, label=legend)
    if tpoint is not None:
        draw_annotate((point.x, point.y), (tpoint.x, tpoint.y), label, arrow)


def draw_dash_line(x1, y1, x2, y2):
    plt.plot([x1, x2], [y1, y2], 'k--', 0.1, alpha=0.3)


def draw_bracket_annotate(point1, point2, arrowstyle):
    plt.gca().annotate('', xy=(point1.x, point1.y),
                       xytext=(point2.x, point2.y),
                       fontsize=20,
                       arrowprops=dict(arrowstyle=arrowstyle, connectionstyle='bar'))


def draw():
    d1 = Point(1.5, 0.5)
    d2 = Point(1.5, 1.5)
    circle_point = (0.5, 0.5)
    cross_point = Point(d1.x, f(d1.x))

    # 绘制坐标
    plt.figure('Bresenham_1', figsize=(6, 6))
    plt.xlim(0, 4)
    plt.ylim(0, 4)
    plt.xticks(np.arange(0, 5, 1))
    plt.yticks(np.arange(0, 5, 1))

    # 绘制理想直线及与d1、d2的交点
    x = np.arange(0, 4)
    plt.plot(x, f(x))  # 理想直线
    draw_piont_with_annotate(cross_point, cross_point+Point(0, 1),
                             psize=110, label='$y=mx_{k+1}+b$', arrow='->')  # 交点

    # 绘制圆
    plt.scatter(circle_point[0], circle_point[1])
    cir1 = Circle(xy=circle_point, radius=0.5, alpha=0.5)
    plt.gca().add_patch(cir1)
    p_at_x = (circle_point[0], 0)
    p_at_y = (0, circle_point[1])
    draw_dash_line(circle_point[0], circle_point[1], p_at_x[0], p_at_x[1])
    draw_dash_line(circle_point[0], circle_point[1], p_at_y[0], p_at_y[1])
    draw_annotate(p_at_x, (p_at_x[0], p_at_x[1] - 0.15), '$x_k$')
    draw_annotate(p_at_y, (p_at_y[0] - 0.2, p_at_y[1]), '$y_k$')

    # 绘制d1, d2,及虚线
    draw_bracket_annotate(Point(d1.x, f(d1.x)), d1, '->')
    draw_annotate((d1.x+0.25, d1.y+0.2), (d1.x+0.25, d1.y+0.2), 'd1')
    draw_bracket_annotate(Point(d2.x, f(d2.x)), d2, '->')
    draw_annotate((d2.x-0.3, d2.y-0.2), (d2.x-0.3, d2.y-0.2), 'd2')
    draw_piont_with_annotate(d1)
    draw_piont_with_annotate(d2)
    draw_dash_line(d2.x, d2.y, 0, d2.y)
    draw_annotate((0, d2.y), (-0.4, d2.y), '$y_{k+1}$')
    draw_dash_line(d2.x, d2.y, d2.x, 0)
    draw_annotate((d2.x, 0), (d2.x, -0.2), '$x_{k+1}$')
    plt.plot()

    # plt.legend()
    plt.gca().set_xticklabels([])
    plt.gca().set_yticklabels([])
    plt.grid(True)
    plt.show()


def main():
    draw()


if __name__ == '__main__':
    main()

 

Class Point

# -- coding: utf-8 --


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)
点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像