《用Python学数学》

processing学习笔记

  • 画函数图像
  • 让正方形做公转运动
  • 让正方形到处乱飞
  • 让正方形做公转加自转运动
  • 可交互的彩虹网格
  • 彩虹三角形万花尺
  • 画正多边形
  • 画正弦波
  • 画万花尺图
  • 画谐波图
  • 芒德布罗集
  • 茹利亚集
  • 动态分形树
  • 科赫雪花
  • 谢尔宾斯基三角形
  • 正方形分形
  • 龙形曲线

《用python学数学》是2021年人民邮电出版社出版的图书,作者是彼得·法雷尔(Peter Farrell)。本书向读者展示如何利用编程来让数学学习变得有意义并且充满乐趣。读者在探索代数学、几何学、三角学、矩阵和元胞自动机等领域的关键数学概念时,将学会在Python语言的帮助下使用代码可视化一系列数学问题的解决方案。

画函数图像

# 设置x的最小值和最大值
xmin = -10
xmax = 10

# 设置y的最小值和最大值
ymin = -10
ymax = 10

# 计算x和y的取值范围
rangex = xmax - xmin
rangey = ymax - ymin

def setup():
    global xscl, yscl
    size(600,600)
    xscl = width / rangex
    yscl = -height / rangey
    
def draw():
    global xscl, yscl
    background(255) # 白色
    translate(width/2, height/2)
    grid(xscl, yscl)
    graphFunction()
    
def f(x):
    return x**2

def graphFunction():
    x = xmin
    while x <= xmax:
        fill(0)
        line(x*xscl, f(x)*yscl, (x+0.1)*xscl, f(x+0.1)*yscl)
        x += 0.1

    
def grid(xscl, yscl):
    # 画一个用于作图的网格
    # 青色的线
    strokeWeight(1)
    stroke(0, 255, 255)
    for i in range(xmin, xmax+1):
        line(i*xscl, ymin*yscl, i*xscl, ymax*yscl)
    for i in range(ymin, ymax+1):
        line(xmin*xscl, i*yscl, xmax*xscl, i*yscl)
    stroke(0) # 黑色的轴
    line(0, ymin*yscl, 0, ymax*yscl)
    line(xmin*xscl, 0, xmax*xscl, 0)

让正方形做公转运动

t = 0

def setup():
    size(600,600)
    
def draw():
    global t
    background(255) # 白色
    translate(width/2, height/2)
    rotate(radians(t))
    for i in range(12):
        rect(200, 0, 50, 50)
        rotate(radians(360/12))
    t += 0.1

让正方形到处乱飞

t = 0

def setup():
    size(600,600)
    
def draw():
    global t
    background(255) # 白色
    translate(width/2, height/2)
    rotate(radians(t))
    for i in range(12):
        translate(200, 0)
        rotate(radians(t))
        rect(0, 0, 50, 50)
        rotate(radians(360/12))
    t += 0.1

让正方形做公转加自转运动

t = 0

def setup():
    size(600,600)
    
def draw():
    global t
    background(255) # 白色
    translate(width/2, height/2)
    rotate(radians(t))
    for i in range(12):
        pushMatrix() # 保存当前方位
        translate(200, 0)
        rotate(radians(t))
        rect(0, 0, 50, 50)
        popMatrix() # 回到当前方位
        rotate(radians(360/12))
    t += 0.1

可交互的彩虹网格

def setup():
    size(600,600)
    rectMode(CENTER)
    colorMode(HSB)
    
def draw():
    global t
    background(0) # 黑色背景
    translate(20, 20)
    for x in range(30):
        for y in range(30):
            d = dist(30*x, 30*y, mouseX, mouseY)
            fill(0.5*d, 255, 255)
            rect(30*x, 30*y, 25, 25)

彩虹三角形万花尺

def setup():
    size(600,600)
    rectMode(CENTER)
    colorMode(HSB)

t = 0

def draw():
    global t
    background(255)
    translate(width/2, height/2)
    for i in range(90):
        # 将三角形绕圆周等间距摆放
        rotate(radians(360/90))
        pushMatrix() # 保存当前方位
        # 平移至圆周
        translate(200, 0)
        # 旋转一定角度
        rotate(radians(t+2*i*360/90))
        # 画出三角形
        stroke(i/9*20, 255, 255)
        tri(100)
        # 回到保存的方位
        popMatrix()
    t += 0.5
    
def tri(length):
    noFill() # 设置三角形为透明
    triangle(0, -length,
             -length*sqrt(3)/2, length/2,
             length*sqrt(3)/2, length/2)

画正多边形

def setup():
    size(600, 600)
    
def draw():
    translate(width/2, height/2)
    polygon(3, 100) # 三条边,顶点距中心100个单位
    
def polygon(sides, sz):
    '''给定边的条数和顶点到中心的距离,画一个正多边形'''
    step = radians(360/sides)
    beginShape()
    for i in range(sides):
        vertex(sz * cos(i * step),
               sz * sin(i * step))
    endShape(CLOSE)

画正弦波

r1 = 100 # 大圆半径
r2 = 10 # 小圆半径
t = 0 # 时间变量
circleList = []

def setup():
    size(600, 600)
    
def draw():
    global t, circleList
    background(200)
    # 平移至窗口左半边中央位置
    translate(width/4, height/2)
    noFill() # 不给大圆填色
    stroke(0) # 黑色轮廓
    ellipse(0, 0, 2*r1, 2*r1)
    
    # 转圈的小圆
    fill(255, 0, 0)
    y = r1*sin(t)
    x = r1*cos(t)
    ellipse(x, y, r2, r2)
    
    # 将点添加至列表
    circleList = [y] + circleList[:245]
    
    # 加上一条绿线
    stroke(0, 255, 0)
    line(x, y, 200, y)
    fill(0, 255, 0)
    ellipse(200, y, 10, 10)
    
    # 遍历circleList画出轨迹
    for i,c in enumerate(circleList):
        # 作为轨迹的小绿圆
        ellipse(200+i, c, 5, 5)
    
    t += 0.05

画万花尺图

# 浮点数要带上小数否则就是整除
r1 = 300.0 # 大圆半径
r2 = 175.0 # 小圆半径
r3 = 5.0   # 圆孔半径
# 大圆位置
x1 = 0
y1 = 0
t = 0    # 时间变量
points = [] # 用来存放点的空列表
prop = 0.9  # 比列变量

def setup():
    size(600, 600)
    
def draw():
    global t, points
    background(255)
    translate(width/2, height/2)
    noFill() # 不填色
    
    # 大圆
    stroke(0) # 黑色轮廓
    ellipse(x1, y1, 2*r1, 2*r1)
    
    # 小圆
    x2 = (r1 - r2)*cos(t)
    y2 = (r1 - r2)*sin(t)
    ellipse(x2, y2, 2*r2, 2*r2)
    
    # 圆孔
    x3 = x2 + prop*(r2-r3)*cos(-(r1-r2)/r2*t)
    y3 = y2 + prop*(r2-r3)*sin(-(r1-r2)/r2*t)
    fill(255, 0, 0)
    ellipse(x3, y3, 2*r3, 2*r3)
    
    # 将点添加至列表
    points = [[x3, y3]] + points[:2000]
    for i, p in enumerate(points):  # 遍历点坐标列表
        if i < len(points)-1:  # 直到倒数第二个点
            stroke(255, 0, 0)  # 两点间用红点连接
            line(p[0], p[1], points[i+1][0], points[i+1][1])
    
    t += 0.05

画谐波图

t = 0
points = []

def setup():
    size(600, 600)
    noStroke()
    
def draw():
    global t, points
    background(255)
    translate(width/2, height/2)
    while t<1000:
        points.append(harmonograph(t))
        t += 0.01
    # 遍历points列表并在相邻坐标之间连线
    for i, p in enumerate(points):
        stroke(255, 0, 0)  # 红色
        if i < len(points) - 1:
            line(p[0], p[1], points[i+1][0], points[i+1][1])
    
def harmonograph(t):
    # 幅度
    a1 = a2 = a3 = a4 = 100
    # 频率
    f1, f2, f3, f4 = 2.01, 3, 3, 2
    # 相位移
    p1, p2, p3, p4 = -PI/2, 0, -PI/16, 0
    # 衰减常数
    d1, d2, d3, d4 = 0.0085, 0.065, 0, 0
    # 模拟两个钟摆的谐波
    x = a1 * cos(f1*t+p1) * exp(-d1*t) + a3 * cos(f3*t+p3)*exp(-d3*t)
    y = a2 * sin(f2*t+p2) * exp(-d2*t) + a4 * sin(f4*t+p4)*exp(-d4*t)
    return [x, y]

芒德布罗集

# x的最小值和最大值
xmin = -2
xmax = 2

# y的最小值和最大值
ymin = -2
ymax = 2

# 计算范围
rangex = xmax - xmin
rangey = ymax - ymin


def setup():
    global xscl, yscl
    size(600, 600)
    colorMode(HSB)
    noStroke()
    xscl = float(rangex) / width
    yscl = float(rangey) / height


def draw():
    # 遍历像素的x坐标和y坐标
    for x in range(width):
        for y in range(height):
            z = [(xmin + x * xscl),
                 (ymin + y * yscl)]
            # 代入mandelbrot函数
            col = mandelbrot(z, 100)
            # 如果函数返回100
            if col == 100:
                fill(0)  # 设置填充色为黑色
            else:
                # fill(3*col, 255, 255)  # 设置填充色为白色
                fill(255-15*col, 255, 255)
            # 画出小正方形
            rect(x, y, 1, 1)


def mandelbrot(z, num):
    """运行该过程num次并返回发散时的次数"""
    count = 0
    # 把z的值赋给z1
    z1 = z
    # 迭代num次
    while count <= num:
        # 检查是否发散
        if magnitude(z1) > 2.0:
            # 返回发散时的迭代次数
            return count
        # 计算新的z1
        z1 = cAdd(cMult(z1, z1), z)
        count += 1
    # 如果最后不发散
    return num


def cAdd(a, b):
    """将两个复数相加"""
    return [a[0] + b[0], a[1] + b[1]]


def cMult(u, v):
    """返回两个复数之积"""
    return [u[0] * v[0] - u[1] * v[1], u[1] * v[0] + u[0] * v[1]]


def magnitude(z):
    return sqrt(z[0] ** 2 + z[1] ** 2)

茹利亚集

# x的最小值和最大值
xmin = -2
xmax = 2

# y的最小值和最大值
ymin = -2
ymax = 2

# 计算范围
rangex = xmax - xmin
rangey = ymax - ymin


def setup():
    global xscl, yscl
    size(600, 600)
    colorMode(HSB)
    noStroke()
    xscl = float(rangex) / width
    yscl = float(rangey) / height


def draw():
    # 将原点移动到窗口中央
    translate(width/2, height/2)
    # 遍历范围内的若干复数
    x = xmin
    while x<xmax:
        y = ymin
        while y<ymax:
            z = [x, y]
            # c = [-0.8, 0.156]
            # c = [-0.4, 0.6]
            c = [0.285, 0.01]
            # 代入julia函数
            col = julia(z, c, 100)
            # 如果函数返回100
            if col == 100:
                fill(0)  # 设置填充色为黑色
            else:
                # fill(3*col, 255, 255)  # 设置填充色为白色
                fill(255-15*col, 255, 255)
            # 画出小正方形
            rect(x/xscl, y/yscl, 1, 1)
            y += 0.01
        x += 0.01


def julia(z, c, num):
    """运行该过程num次并返回发散时的次数"""
    count = 0
    # 把z的值赋给z1
    z1 = z
    # 迭代num次
    while count <= num:
        # 检查是否发散
        if magnitude(z1) > 2.0:
            # 返回发散时的迭代次数
            return count
        # 计算新的z1
        z1 = cAdd(cMult(z1, z1), c)
        count += 1
    # 如果最后不发散
    return num


def cAdd(a, b):
    """将两个复数相加"""
    return [a[0] + b[0], a[1] + b[1]]


def cMult(u, v):
    """返回两个复数之积"""
    return [u[0] * v[0] - u[1] * v[1], u[1] * v[0] + u[0] * v[1]]


def magnitude(z):
    return sqrt(z[0] ** 2 + z[1] ** 2)

动态分形树

def setup():
    size(600, 600)
    
def draw():
    background(255)
    translate(300, 500)
    level = int(map(mouseX, 0, width, 0, 15))
    y(100, level)
    
def y(sz, level):
    if level>0:
        line(0, 0, 0, -sz)
        translate(0, -sz)
        angle = map(mouseY, 0, height, 0, 180)
        rotate(radians(angle))
        y(0.8*sz, level-1)  # 右树枝
        rotate(radians(-2*angle))
        y(0.8*sz, level-1)  # 左树枝
        rotate(radians(angle))
        translate(0, sz)

科赫雪花

def setup():
    size(600, 600)
    
def draw():
    background(255)
    translate(100, height/2-100)
    level = int(map(mouseX, 0, width, 0, 7))
    snowflake(400, level)
    
def snowflake(sz, level):
    for i in range(3):
        segment(sz, level)
        rotate(radians(120))

def segment(sz, level):
    if level == 0:
        line(0, 0, sz, 0)
        translate(sz, 0)
    else:
        segment(sz/3.0, level-1)
        rotate(radians(-60))
        segment(sz/3.0, level-1)
        rotate(radians(120))
        segment(sz/3.0, level-1)
        rotate(radians(-60))
        segment(sz/3.0, level-1)

谢尔宾斯基三角形

def setup():
    size(600, 600)
    
def draw():
    background(255)
    translate(50, 450)
    sierpinski(400, 8)
    
def sierpinski(sz, level):
    if level == 0:  # 画一个黑色三角形
        fill(0)
        triangle(0, 0, sz, 0, sz/2.0, -sz*sqrt(3)/2.0)
    else:  # 在每个顶点画出谢尔宾斯基三角形
        for i in range(3):
            sierpinski(sz/2.0, level-1)
            translate(sz, 0)
            rotate(radians(-120))

正方形分形

def setup():
    size(600, 600)
    fill(128, 0, 128)  # 紫色
    noStroke()
    
def draw():
    background(255)
    translate(50, 50)
    level = int(map(mouseX, 0, width, 0, 7))
    squareFractal(500, level)
    
def squareFractal(sz, level):
    if level == 0:
        rect(0, 0, sz, sz)
    else:
        pushMatrix()
        squareFractal(sz/2.0, level-1)
        translate(sz/2.0, 0)
        squareFractal(sz/2.0, level-1)
        translate(-sz/2.0, sz/2.0)
        squareFractal(sz/2.0, level-1)    
        popMatrix()

龙形曲线

RED = color(255, 0, 0)
BLACK = color(0)

def setup():
    global thelevel, size1
    size(600, 600)
    thelevel = 5
    size1 = 40
    
def draw():
    global thelevel
    background(255)
    translate(width/2, height/2)
    angle = map(mouseX, 0, width, 0, 2*PI)
    stroke(RED)
    strokeWeight(3)
    pushMatrix()
    leftDragon(size1, thelevel)
    popMatrix()
    leftDragon(size1, thelevel-1)
    rotate(angle)
    stroke(BLACK)
    rightDragon(size1, thelevel-1)
    
def leftDragon(sz, level):
    if level == 0:
        line(0, 0, sz, 0)
        translate(sz, 0)
    else:
        leftDragon(sz, level-1)
        rotate(radians(-90))
        rightDragon(sz, level-1)
        
def rightDragon(sz, level):
    if level == 0:
        line(0, 0, sz, 0)
        translate(sz, 0)
    else:
        leftDragon(sz, level-1)
        rotate(radians(90))
        rightDragon(sz, level-1)

def keyPressed():
    global thelevel, size1
    if key == CODED:
        if keyCode == UP:
            thelevel += 1
        if keyCode == DOWN:
            thelevel -= 1
        if keyCode == LEFT:
            thelevel -= 5
        if keyCode == RIGHT:
            thelevel += 5

你可能感兴趣的:(图书馆,python)