用Python画小黄人

from PIL import Image
import numpy as np
# 中点直线法
def MidPointLine(x1, y1, x2, y2):  # 传入两个点(x1,y1)和(x2,y2),画出通过这两点的直线
    tag = 0
    dx = x2 - x1  # x的距离
    dy = y2 - y1  # y的距离
    if abs(dx) < abs(dy):  # 如果 |k| >1 ,坐标互换
        x1, y1 = y1, x1  # 坐标互换
        x2, y2 = y2, x2  # 坐标互换
        tag = 1
    if x1 > x2:  # 确保x1 < x2
        x1, x2 = x2, x1  # 坐标互换
        y1, y2 = y2, y1  # 坐标互换
    a = y1 - y2
    b = x2 - x1
    d = a + (b / 2)  # d为中点带入到直线方程的值
    if y1 < y2:  # 斜率 > 0
        x = x1  # 初始点的x坐标
        y = y1  # 初始点的y坐标
        while x < x2:  # 没画到最后

            if d < 0:  # 中点位于直线下方
                x = x + 1  # 直线靠近(x+1,y+1),所以y要加一
                y = y + 1  # 直线靠近(x+1,y+1),所以x要加一
                d = d + a + b
            else:  # 中点位于直线上方
                x = x + 1  # 直线靠近(x+1,y),所以x要加一
                d = d + a
            if tag:  # 斜率 > 1
                img[x, y] = 1
            else:
                img[y, x] = 1
    else:  # 斜率 <= 0
        x = x2  # 初始点的x坐标
        y = y2  # 初始点的y坐标
        while x > x1:  # 没画到最后
            if d < 0:  # 中点位于直线下方
                y = y + 1  # 直线靠近(x-1,y+1),所以y要加一
                x = x - 1  # 直线靠近(x-1,y+1),所以x要减一
                d = d - a + b
            else:  # 中点位于直线上方
                x = x - 1  # 直线靠近(x-1,y),所以x要减一
                d = d - a
            if tag:
                img[x, y] = 1
            else:
                img[y, x] = 1

# Bresenham算法
def Bresenham(x1, y1, x2, y2):
    dx = abs(x2 - x1)  # 水平偏移量
    dy = abs(y2 - y1)  # 垂直偏移量
    sx = 1 if x2 > x1 else -1  # 每次的增量
    sy = 1 if y2 > y1 else -1  # 每次的增量
    erro = dx / 2 if dx > dy else -dy / 2
    while x1 != x2 or y1 != y2:  # 没画到最后
        img[y1, x1] = 1
        e2 = erro
        if e2 > -dx:
            erro -= dy
            x1 += sx  # 下一个点是(x+sx,y)
        if e2 < dy:
            erro += dx
            y1 += sy  # 下一个点是(x,y+sy)


# 中点圆算法
def Circle_Midpoint(x0, y0, r):  # 输入圆心和半径
    tx = 0
    ty = r
    d = 1.25 - r  # 初始点在(0,r)
    while tx <= ty:
        # 利用圆的八分对称性画点
        img[y0 + tx, x0 + ty] = 1
        img[y0 + tx, x0 - ty] = 1
        img[y0 - tx, x0 + ty] = 1
        img[y0 - tx, x0 - ty] = 1
        img[y0 + ty, x0 + tx] = 1
        img[y0 + ty, x0 - tx] = 1
        img[y0 - ty, x0 + tx] = 1
        img[y0 - ty, x0 - tx] = 1
        if d < 0:  # 当d<0时,下一个点是(x,y-1)
            d += 2 * tx + 3
        else:  # 当d>=0时,下一个点是(x,y-1)
            d += 2 * (tx - ty) + 5
            ty -= 1
        tx += 1


# 中点圆算法(画半圆)
def Circle_Midpoint2(x0, y0, r):  # 输入圆心和半径
    tx = 0
    ty = r
    d = 1.25 - r  # 初始点在(0,r)
    while tx <= ty:
        # 利用圆的八分对称性画点
        img[y0 + tx, x0 + ty] = 1
        img[y0 + tx, x0 - ty] = 1
        img[y0 + ty, x0 + tx] = 1
        img[y0 + ty, x0 - tx] = 1
        if d < 0:  # 当d<0时,下一个点是(x,y-1)
            d += 2 * tx + 3
        else:  # 当d>=0时,下一个点是(x,y-1)
            d += 2 * (tx - ty) + 5
            ty -= 1
        tx += 1
# 中点圆算法(画上半圆)
def Circle_Midpoint3(x0, y0, r):  # 输入圆心和半径
    tx = 0
    ty = r
    d = 1.25 - r  # 初始点在(0,r)
    while tx <= ty:
        # 利用圆的八分对称性画点
        img[y0 - tx, x0 + ty] = 1
        img[y0 - tx, x0 - ty] = 1
        img[y0 - ty, x0 + tx] = 1
        img[y0 - ty, x0 - tx] = 1
        if d < 0:  # 当d<0时,下一个点是(x,y-1)
            d += 2 * tx + 3
        else:  # 当d>=0时,下一个点是(x,y-1)
            d += 2 * (tx - ty) + 5
            ty -= 1
        tx += 1
def Circle_Midpoint4(x0, y0, r):  # 输入圆心和半径
    tx = 0
    ty = r
    d = 1.25 - r  # 初始点在(0,r)
    while tx <= ty:
        # 利用圆的八分对称性画点
        img[y0 + tx, x0 + ty] = 1  # 绘制像素点
        if d < 0:  # 当d<0时,下一个点是(x,y-1)
            d += 2 * tx + 3
        else:  # 当d>=0时,下一个点是(x,y-1)
            d += 2 * (tx - ty) + 5
            ty -= 1
        tx += 1
def Circle_Midpoint5(x0, y0, r):  # 输入圆心和半径
    tx = 0
    ty = r
    d = 1.25 - r  # 初始点在(0,r)
    while tx <= ty:
        # 利用圆的八分对称性画点
        img[y0 - tx, x0 + ty] = 1
        if d < 0:  # 当d<0时,下一个点是(x,y-1)
            d += 2 * tx + 3
        else:  # 当d>=0时,下一个点是(x,y-1)
            d += 2 * (tx - ty) + 5
            ty -= 1
        tx += 1
def Circle_Midpoint6(x0, y0, r):  # 输入圆心和半径
    tx = 0
    ty = r
    d = 1.25 - r  # 初始点在(0,r)
    while tx <= ty:
        # 利用圆的八分对称性画点
        img[y0 + tx, x0-ty] = 1

        img[y0 - tx, x0-ty] = 1
        if d < 0:  # 当d<0时,下一个点是(x,y-1)
            d += 2 * tx + 3
        else:  # 当d>=0时,下一个点是(x,y-1)
            d += 2 * (tx - ty) + 5
            ty -= 1
        tx += 1
def Circle_Midpoint7(x0, y0, r):  # 输入圆心和半径
    tx = 0
    ty = r
    d= 1.25-r  # 初始点在(0,r)
    while tx <= ty:
        # 利用圆的八分对称性画点
        img[y0 - tx, x0 + ty] = 1  # 绘制像素点
        img[y0 - tx, x0 - ty] = 1  # 绘制像素点
        d=d+ 2 * tx + 3
    else:  # 当d>=0时,下一个点是(x,y-1)
            d += 2 * (tx - ty) + 5
            ty -= 1
    tx += 1
def Circle_Midpoint8(x0, y0, r):  # 输入圆心和半径
    tx = 0
    ty = r
    d = 1.25 - r  # 初始点在(0,r)
    while tx <= ty:
        # 利用圆的八分对称性画点
        img[y0 - tx, x0 - ty] = 1  # 绘制像素点
        if d < 0:  # 当d<0时,下一个点是(x,y-1)
            d += 2 * tx + 3
        else:  # 当d>=0时,下一个点是(x,y-1)
            d += 2 * (tx - ty) + 5
            ty -= 1
        tx += 1
def draw(x, y):
    Circle_Midpoint2(int(x / 2), int(y / 2) +100, 150)  # 身体的下半个圆
    Bresenham(int(x / 2) -150, int(y / 2) - 150, int(x / 2) -150, int(y / 1.36)-80)  # 左边身体的直线
    Bresenham(int(x / 2)+150, int(y / 2) - 150, int(x / 2)+150, int(y / 1.36)-80 )  # 右边身体的直线
    Circle_Midpoint3(int(x / 2), int(y / 2) -150, 150)  # 身体的上半个圆
    Circle_Midpoint(int(x / 1.75)-20, int(y / 2.8), 40)  # 右眼睛
    Circle_Midpoint(int(x / 2.3)-20, int(y / 2.8), 40)  # 左眼
    for i in range(17, 21):
        Circle_Midpoint(int(x / 1.75), int(y / 2.8), i)
        Circle_Midpoint(int(x / 2.3), int(y / 2.8), i)
    Circle_Midpoint2(int(x / 2)-10, int(y / 2) -50, 50)  # 身体的下半个圆
    # 小胳膊
    Bresenham(int(x / 2) + 150, int(y / 2) - 20, int(x / 2) + 200, int(y / 2) + 40)
    Bresenham(int(x / 2) - 150, int(y / 2) - 20, int(x / 2) - 200, int(y / 2) + 40)
    Bresenham(int(x / 2) + 200, int(y / 2) + 40, int(x / 2) + 150, int(y / 2) + 100)
    Bresenham(int(x / 2) - 200, int(y / 2) + 40, int(x / 2) - 150, int(y / 2) + 100)
    #  小腿
    Bresenham(int(x / 2) - 70, int(y / 1.36) + 47, int(x / 2) - 70, int(y / 1.36) + 100)  # 左腿
    Bresenham(int(x / 2) - 50, int(y / 1.36) + 52, int(x / 2) - 50, int(y / 1.36) + 120)
    Bresenham(int(x / 2) - 50, int(y / 1.36) + 120, int(x / 2) - 100, int(y / 1.36) + 120)
    Bresenham(int(x / 2) - 70, int(y / 1.36) + 100, int(x / 2) - 100, int(y / 1.36) + 100)
    Circle_Midpoint5(int(x / 2) + 90, int(y / 2) + 310, 30)  # 右边的鞋
    Circle_Midpoint6(int(x / 2) - 90, int(y / 2) + 298, 15)  # 左边的鞋
    Bresenham(int(x / 2) + 70, int(y / 1.36) + 47, int(x / 2) + 70, int(y / 1.36) + 100)  # 右腿
    Bresenham(int(x / 2) + 50, int(y / 1.36) + 52, int(x / 2) + 50, int(y / 1.36) + 120)
    Bresenham(int(x / 2) + 50, int(y / 1.36) + 120, int(x / 2) + 117, int(y / 1.36) + 120)
    Bresenham(int(x / 2) + 70, int(y / 1.36) + 100, int(x / 2) + 110, int(y / 1.36) + 100)
    # 头发
    Circle_Midpoint4(int(x / 2) - 250, int(y / 2) - 395, 200)  # 左边那根毛
    Circle_Midpoint8(int(x / 2) + 250, int(y / 2) - 290, 200)  # 右毛
    Bresenham(int(x / 2) , int(y / 1.36) -580, int(x / 2), int(y / 1.36) -490)  # 中间毛
    Bresenham(int(x / 2) -80, int(y / 1.36)-150  ,int( x / 2) + 80, int(y / 1.36)-150 )  # 衣服
    Bresenham(int(x / 2) - 80, int(y / 1.36) - 150, int(x / 2) - 80, int(y / 1.36)-50)  # 衣服左边那个竖
    Bresenham(int(x / 2) + 80, int(y / 1.36) - 150, int(x / 2) + 80, int(y / 1.36) - 50)  # 衣服右边那个竖
    Bresenham(int(x / 2) - 147, int(y / 1.36) - 50, int(x / 2) -80, int(y / 1.36) - 50)  # 衣服下面那个左横线
    Bresenham(int(x / 2) + 147, int(y / 1.36) - 50, int(x / 2)+ 80, int(y / 1.36) - 50)  # 衣服下面那个右横线
    Bresenham(int(x / 2) - 50, int(y / 1.36) - 115, int(x / 2) +50, int(y / 1.36) - 115)  # 小口袋的横线
    Circle_Midpoint2(int(x / 2), int(y / 2) +75, 50)  # 口袋的下半个圆
    Bresenham(int(x / 2) -150, int(y / 1.36) -255, int(x / 2) -80, int(y / 1.36)-150)   # 背带裤的左带子
    Bresenham(int(x / 2)+150, int(y / 1.36) - 255, int(x / 2) +80, int(y / 1.36)-150 )  # 背带裤的左带子
if __name__ == '__main__':
    high = 800  # 画布的宽
    width = 800  # 画布的高
    img = np.zeros([high, width])
    for i in range(high):  # 白色图片
        for j in range(width):
            img[i, j] = 250
    draw(high, width)  # 绘图
    #Circle_Bresenham(100,100,50)
    img = Image.fromarray(img.astype('uint8')).convert('RGB')
    img.show()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值