Python实例:爱心代码

前言

在编程的奇妙世界里,代码不仅仅是冰冷的指令集合,它还可以成为表达情感、传递温暖的独特方式。今天,我们将一同探索用 Python 语言绘制爱心的神奇之旅。

爱心,这个象征着爱与温暖的符号,一直以来都在人类的情感世界中占据着特殊的地位。而通过 Python 的强大功能,我们可以将这一美好的象征以数字化的形式呈现出来。

无论是向心爱的人表达爱意,还是为了给自己的编程之旅增添一抹浪漫的色彩,这段 Python 爱心代码都将成为你手中的魔法棒。它不仅仅是一段代码,更是一份情感的寄托,一个创意的表达。

在接下来的代码中,我们将运用 Python 的绘图库和数学知识,精心构建一个充满爱意的爱心图案。每一行代码都像是一个小小的画笔,共同勾勒出这份独特的情感画卷。让我们一起沉浸在编程的乐趣中,感受代码与爱心的完美融合。

爱心代码

通过使用turtle库实现画爱心

pip安装步骤

同时按Win+R键,调出“运行”对话框;

fbdf5e0a66d5443ca6887de2c144148f.png

然后在对话框中输入cmd,敲回车键运行;

76ccd1e102ae4555b2cbce789a37c6ae.png

进入【cmd.exe】界面;

df67da7a40d34c98806971c3fff7ab14.png

在【cmd.exe】中输入安装命令:pip install turtle

安装成功后如下图所示:

使用turtle库可以绘制很多不同的图形

多边形

绘制三角形:

import turtle

t = turtle.Turtle()

for _ in range(3):
    t.forward(100)
    t.left(120)

turtle.done()

正方形:

import turtle

t = turtle.Turtle()

for _ in range(4):
    t.forward(100)
    t.left(90)

turtle.done()

正五边形:

import turtle

t = turtle.Turtle()

for _ in range(5):
    t.forward(100)
    t.left(72)

turtle.done()
圆形和弧形

圆形:

import turtle

t = turtle.Turtle()

t.circle(50)

turtle.done()

半圆:

import turtle

t = turtle.Turtle()

t.circle(50, 180)

turtle.done()
螺旋图形

螺旋线:

import turtle

t = turtle.Turtle()
for i in range(100):
    t.forward(i * 5)
    t.right(144)

turtle.done()
花朵形状

简单花朵:

import turtle

t = turtle.Turtle()

for _ in range(12):
    t.circle(50)
    t.right(30)

turtle.done()
星星形状

五角星:

import turtle

t = turtle.Turtle()

for _ in range(5):
    t.forward(100)
    t.right(144)

turtle.done()

Python代码实现

代码展示

这段代码使用turtle库的函数来控制画笔绘制一个红色的爱心图形。你可以根据需要调整画笔速度和颜色等参数。

import turtle

# 设置画笔速度和颜色
t = turtle.Turtle()
t.speed(3)
t.color("red")

# 绘制爱心
def draw_heart():
    t.begin_fill()
    t.left(140)
    t.forward(111.65)
    t.circle(-45, 195)
    t.left(120)
    t.circle(-45, 195)
    t.forward(111.65)
    t.end_fill()

draw_heart()

turtle.done()

代码逐行注释

import turtle

# 设置画笔速度和颜色
t = turtle.Turtle()  # 创建一个 turtle 对象,命名为 t
t.speed(3)  # 设置画笔移动速度为 3,值越大速度越快
t.color("red")  # 设置画笔颜色为红色

# 绘制爱心
def draw_heart():
    t.begin_fill()  # 开始填充图形
    t.left(140)  # 向左旋转 140 度
    t.forward(111.65)  # 向前移动 111.65 个单位长度
    t.circle(-45, 195)  # 以半径为 -45 画 195 度的弧
    t.left(120)  # 再次向左旋转 120 度
    t.circle(-45, 195)  # 以半径为 -45 画另一段 195 度的弧
    t.forward(111.65)  # 向前移动 111.65 个单位长度,回到起始位置
    t.end_fill()  # 结束填充图形

draw_heart()  # 调用函数绘制爱心

turtle.done()  # 使窗口保持打开状态,等待用户关闭

运行思路

以下是这段代码的运行思路:

  • 首先导入turtle模块,这个模块提供了绘制图形的功能。
  • 创建一个turtle对象t,它将用于执行各种绘图操作。
  • 设置画笔的移动速度为3,这样在绘制图形时可以看到画笔的移动过程,速度适中既不会太快让人看不清,也不会太慢影响体验。
  • 设置画笔的颜色为 “红色”,确定绘制爱心的颜色。
  • 定义一个函数draw_heart来专门绘制爱心。
    • 在这个函数中,首先调用t.begin_fill()表示开始填充图形,后续封闭的图形内部将被填充颜色。
    • 然后通过t.left(140)将画笔向左旋转140度,为绘制爱心的起始角度做准备。
    • t.forward(111.65)让画笔向前移动特定长度,这是爱心的一部分线条。
    • t.circle(-45, 195)以半径为-45画一个195度的圆弧,这是爱心的一个弯曲部分。
    • t.left(120)再次向左旋转120度,调整画笔方向以绘制爱心的另一部分。
    • 再次调用t.circle(-45, 195)画另一段圆弧。
    • 最后通过t.forward(111.65)回到起始位置,完成爱心的轮廓。
    • 调用t.end_fill()结束填充,此时爱心内部将被填充为之前设置的颜色。
  • 调用draw_heart()函数开始绘制爱心。
  • 最后,turtle.done()确保程序运行结束后绘图窗口不会立即关闭,而是保持打开状态,以便用户查看绘制好的爱心图形。

Python实现效果图

  代码效果图:

  代码实现效果图:

修改代码

下面是一个更复杂的 Python 爱心代码,其中加入了一些动态效果和颜色变化:

import turtle
import time
import random

# 设置窗口
window = turtle.Screen()
window.bgcolor("black")
window.title("Complex Heart")

# 创建画笔
pen = turtle.Turtle()
pen.speed(0)
pen.pensize(2)

# 定义颜色列表
colors = ["red", "pink", "purple", "orange"]

# 绘制爱心函数
def draw_heart(size):
    pen.begin_fill()
    pen.left(140)
    pen.forward(size)
    pen.circle(-size/2, 195)
    pen.left(120)
    pen.circle(-size/2, 195)
    pen.forward(size)
    pen.end_fill()

# 绘制多个爱心并动态变化
for _ in range(50):
    x = random.randint(-300, 300)
    y = random.randint(-300, 300)
    color = random.choice(colors)
    pen.penup()
    pen.goto(x, y)
    pen.pendown()
    pen.color(color)
    size = random.randint(20, 100)
    draw_heart(size)

# 显示文字
pen.penup()
pen.goto(0, -200)
pen.color("white")
pen.write("Love is in the air!", align="center", font=("Arial", 20, "bold"))

# 结束绘制
turtle.done()
代码逐行注释
import turtle
import time
import random

# 设置窗口
window = turtle.Screen()  # 创建一个 turtle 绘图窗口对象
window.bgcolor("black")  # 将窗口背景颜色设置为黑色
window.title("Complex Heart")  # 设置窗口标题为"Complex Heart"

# 创建画笔
pen = turtle.Turtle()  # 创建一个 turtle 画笔对象,命名为 pen
pen.speed(0)  # 设置画笔移动速度为最快(0)
pen.pensize(2)  # 设置画笔的粗细为 2

# 定义颜色列表
colors = ["red", "pink", "purple", "orange"]  # 创建一个包含多种颜色的列表

# 绘制爱心函数
def draw_heart(size):
    pen.begin_fill()  # 开始填充图形
    pen.left(140)  # 向左旋转 140 度
    pen.forward(size)  # 向前移动指定大小的距离
    pen.circle(-size/2, 195)  # 以负半径画 195 度的圆弧
    pen.left(120)  # 再次向左旋转 120 度
    pen.circle(-size/2, 195)  # 再次以负半径画 195 度的圆弧
    pen.forward(size)  # 向前移动指定大小的距离,回到起始位置
    pen.end_fill()  # 结束填充图形

# 绘制多个爱心并动态变化
for _ in range(50):  # 循环 50 次
    x = random.randint(-300, 300)  # 生成一个 -300 到 300 之间的随机整数作为 x 坐标
    y = random.randint(-300, 300)  # 生成一个 -300 到 300 之间的随机整数作为 y 坐标
    color = random.choice(colors)  # 从颜色列表中随机选择一种颜色
    pen.penup()  # 抬起画笔,移动时不绘制线条
    pen.goto(x, y)  # 将画笔移动到指定的坐标位置
    pen.pendown()  # 放下画笔,准备绘制
    pen.color(color)  # 设置画笔颜色为随机选择的颜色
    size = random.randint(20, 100)  # 生成一个 20 到 100 之间的随机整数作为爱心大小
    draw_heart(size)  # 调用函数绘制爱心

# 显示文字
pen.penup()  # 抬起画笔
pen.goto(0, -200)  # 将画笔移动到坐标 (0, -200)
pen.color("white")  # 设置画笔颜色为白色
pen.write("Love is in the air!", align="center", font=("Arial", 20, "bold"))  # 在当前位置书写文字

# 结束绘制
turtle.done()  # 使窗口保持打开状态,等待用户关闭
运行思路
  • 导入必要的模块:

    • turtle模块用于绘图。
    • time模块虽然在这段代码中未被显式使用,但可能在后续扩展中用于控制动画的时间间隔等。
    • random模块用于生成随机数。
  • 设置窗口:

    • 创建一个turtle绘图窗口对象window
    • 将窗口背景颜色设置为黑色,通过window.bgcolor("black")
    • 设置窗口标题为 “Complex Heart”,使用window.title("Complex Heart")
  • 创建画笔:

    • 创建一个turtle画笔对象pen
    • 设置画笔移动速度为最快(速度参数为 0),pen.speed(0),这样在绘制时可以快速完成,减少等待时间。
    • 设置画笔的粗细为 2,pen.pensize(2)
  • 定义颜色列表:

    • 创建一个包含多种颜色的列表colors,其中包含 “red”(红色)、“pink”(粉色)、“purple”(紫色)和 “orange”(橙色)等颜色,用于给爱心随机上色。
  • 绘制多个爱心并动态变化:

    • 使用一个循环,循环次数为 50 次。
    • 在每次循环中:
      • 生成随机的坐标值xy,范围在 -300 到 300 之间,x = random.randint(-300, 300)y = random.randint(-300, 300)。这将决定每个爱心在窗口中的位置。
      • 从颜色列表中随机选择一种颜色赋给colorcolor = random.choice(colors)
      • 抬起画笔,pen.penup(),移动到随机生成的坐标位置,pen.goto(x, y),然后放下画笔,pen.pendown()
      • 生成一个随机的爱心大小size,范围在 20 到 100 之间,size = random.randint(20, 100)
      • 使用随机选择的颜色设置画笔颜色,pen.color(color)
      • 调用draw_heart(size)函数绘制爱心,传入随机生成的大小参数。
  • 显示文字:

    • 抬起画笔,pen.penup()
    • 将画笔移动到坐标 (0, -200),pen.goto(0, -200)
    • 设置画笔颜色为白色,pen.color("white")
    • 使用指定的字体、大小和对齐方式在当前位置书写文字 “Love is in the air!”,pen.write("Love is in the air!", align="center", font=("Arial", 20, "bold"))
  • 结束绘制:

    • 调用turtle.done()使窗口保持打开状态,等待用户关闭窗口。这样用户可以查看绘制好的图形。
Python实现效果图
代码效果图

代码实现效果图

呼吸效果修改

更加复杂绚丽且带有呼吸效果的 Python 爱心代码:

import turtle
import time
import random

# 设置窗口
window = turtle.Screen()
window.bgcolor("black")
window.title("Complex Heart with Breathing Effect")

# 创建画笔
pen = turtle.Turtle()
pen.speed(0)
pen.pensize(2)

# 定义颜色列表
colors = ["red", "pink", "purple", "orange", "magenta", "cyan"]

# 绘制爱心函数
def draw_heart(size):
    pen.begin_fill()
    pen.left(140)
    pen.forward(size)
    pen.circle(-size/2, 195)
    pen.left(120)
    pen.circle(-size/2, 195)
    pen.forward(size)
    pen.end_fill()

# 呼吸效果函数
def breathing_effect(size):
    while True:
        for i in range(10):
            pen.clear()
            new_size = size + i
            draw_heart(new_size)
            time.sleep(0.05)
        for i in range(10):
            pen.clear()
            new_size = size + 9 - i
            draw_heart(new_size)
            time.sleep(0.05)

# 绘制多个爱心并动态变化
for _ in range(50):
    x = random.randint(-300, 300)
    y = random.randint(-300, 300)
    color = random.choice(colors)
    pen.penup()
    pen.goto(x, y)
    pen.pendown()
    pen.color(color)
    size = random.randint(20, 100)
    draw_heart(size)
    breathing_effect(size)

# 显示文字
pen.penup()
pen.goto(0, -200)
pen.color("white")
pen.write("Love is in the air!", align="center", font=("Arial", 20, "bold"))

# 结束绘制
turtle.done()
逐行注释
import turtle
import time
import random

# 设置窗口
window = turtle.Screen()  # 创建一个 turtle 绘图窗口对象
window.bgcolor("black")  # 将窗口背景颜色设置为黑色
window.title("Complex Heart with Breathing Effect")  # 设置窗口标题

# 创建画笔
pen = turtle.Turtle()  # 创建一个 turtle 画笔对象
pen.speed(0)  # 设置画笔移动速度为最快
pen.pensize(2)  # 设置画笔粗细为 2

# 定义颜色列表
colors = ["red", "pink", "purple", "orange", "magenta", "cyan"]  # 可用于爱心的颜色列表

# 绘制爱心函数
def draw_heart(size):
    pen.begin_fill()  # 开始填充图形
    pen.left(140)  # 向左旋转 140 度
    pen.forward(size)  # 向前移动指定大小的距离
    pen.circle(-size/2, 195)  # 以负半径画 195 度的圆弧
    pen.left(120)  # 再次向左旋转 120 度
    pen.circle(-size/2, 195)  # 再次以负半径画 195 度的圆弧
    pen.forward(size)  # 向前移动指定大小的距离,回到起始位置
    pen.end_fill()  # 结束填充图形

# 呼吸效果函数
def breathing_effect(size):
    while True:  # 无限循环以实现持续的呼吸效果
        for i in range(10):  # 逐渐增大爱心尺寸
            pen.clear()  # 清除之前的图形
            new_size = size + i  # 计算新的爱心尺寸
            draw_heart(new_size)  # 绘制新尺寸的爱心
            time.sleep(0.05)  # 暂停一小段时间,控制动画速度
        for i in range(10):  # 逐渐减小爱心尺寸
            pen.clear()  # 清除之前的图形
            new_size = size + 9 - i  # 计算新的爱心尺寸
            draw_heart(new_size)  # 绘制新尺寸的爱心
            time.sleep(0.05)  # 暂停一小段时间,控制动画速度

# 绘制多个爱心并动态变化
for _ in range(50):  # 循环 50 次,绘制多个爱心
    x = random.randint(-300, 300)  # 随机生成 x 坐标
    y = random.randint(-300, 300)  # 随机生成 y 坐标
    color = random.choice(colors)  # 从颜色列表中随机选择一种颜色
    pen.penup()  # 抬起画笔
    pen.goto(x, y)  # 移动到随机坐标位置
    pen.pendown()  # 放下画笔
    pen.color(color)  # 设置画笔颜色为随机选择的颜色
    size = random.randint(20, 100)  # 随机生成爱心尺寸
    draw_heart(size)  # 绘制爱心
    breathing_effect(size)  # 为每个爱心添加呼吸效果

# 显示文字
pen.penup()  # 抬起画笔
pen.goto(0, -200)  # 移动到指定坐标位置
pen.color("white")  # 设置画笔颜色为白色
pen.write("Love is in the air!", align="center", font=("Arial", 20, "bold"))  # 书写文字

# 结束绘制
turtle.done()  # 使窗口保持打开状态,等待用户关闭
运行思路
  • 导入模块:

    • turtle模块用于图形绘制。
    • time模块用于控制时间间隔,实现动画效果。
    • random模块用于生成随机数。
  • 设置窗口:

    • 创建一个turtle绘图窗口对象window
    • 将窗口背景颜色设置为黑色,window.bgcolor("black"),营造出特定的氛围。
    • 设置窗口标题为 “Complex Heart with Breathing Effect”,window.title("Complex Heart with Breathing Effect")
  • 创建画笔:

    • 创建一个turtle画笔对象pen
    • 设置画笔移动速度为最快,pen.speed(0),这样在绘制时可以快速呈现效果。
    • 设置画笔粗细为 2,pen.pensize(2)
  • 定义颜色列表:

    • 创建一个包含多种颜色的列表colors,这些颜色将用于绘制不同的爱心。
  • 定义绘制爱心的函数:

    • draw_heart(size)函数用于绘制一个特定大小的爱心。
    • 首先,开始填充图形,pen.begin_fill()
    • 然后,通过一系列的移动和画弧操作,使用给定的大小参数size,绘制出爱心的形状。
    • 最后,结束填充图形,pen.end_fill()
  • 定义呼吸效果函数:

    • breathing_effect(size)函数实现爱心的呼吸效果。
    • 使用一个无限循环while True,确保呼吸效果持续进行。
    • 在循环中,通过两个嵌套的for循环来逐渐增大和减小爱心的尺寸。
    • 每次循环中,先清除之前的图形,pen.clear()
    • 然后计算新的爱心尺寸,new_size = size + inew_size = size + 9 - i
    • 调用draw_heart(new_size)绘制新尺寸的爱心。
    • 使用time.sleep(0.05)暂停一小段时间,控制动画的速度,使呼吸效果看起来更加自然。
  • 绘制多个爱心并动态变化:

    • 使用一个循环,循环次数为 50 次。
    • 在每次循环中:
      • 生成随机的坐标值xy,范围在 -300 到 300 之间,x = random.randint(-300, 300)y = random.randint(-300, 300),确定每个爱心在窗口中的位置。
      • 从颜色列表中随机选择一种颜色赋给colorcolor = random.choice(colors)
      • 抬起画笔,pen.penup(),移动到随机生成的坐标位置,pen.goto(x, y),然后放下画笔,pen.pendown()
      • 生成一个随机的爱心大小size,范围在 20 到 100 之间,size = random.randint(20, 100)
      • 使用随机选择的颜色设置画笔颜色,pen.color(color)
      • 调用draw_heart(size)绘制爱心。
      • 接着调用breathing_effect(size)为每个爱心添加呼吸效果。
  • 显示文字:

    • 抬起画笔,pen.penup()
    • 将画笔移动到坐标 (0, -200),pen.goto(0, -200)
    • 设置画笔颜色为白色,pen.color("white")
    • 使用指定的字体、大小和对齐方式在当前位置书写文字 “Love is in the air!”,pen.write("Love is in the air!", align="center", font=("Arial", 20, "bold"))
  • 结束绘制:

    • 调用turtle.done()使窗口保持打开状态,等待用户关闭窗口。这样用户可以查看绘制好的图形和动画效果。
Python实现效果图
代码效果图

代码实现效果图

不同编程语言实现

一、Python 使用 turtle 库
import turtle
import math

# 设置画笔速度和填充颜色模式
t = turtle.Turtle()
t.speed(5)
turtle.colormode(255)

# 绘制爱心并实现颜色渐变
def draw_heart_and_gradient():
    for angle in range(0, 360):
        r = 150 - 150 * math.sin(math.radians(angle))
        x = r * math.cos(math.radians(angle))
        y = r * math.sin(math.radians(angle))
        t.penup()
        t.goto(x, y)
        t.pendown()
        # 设置颜色渐变,这里根据角度调整 RGB 值
        t.color(int(255 * (angle / 360)), int(150 * (angle / 360)), int(200 * (angle / 360)))
        t.begin_fill()
        t.circle(5)
        t.end_fill()

draw_heart_and_gradient()

turtle.done()
代码逐行注释
import turtle
import math

# 设置画笔速度和填充颜色模式
t = turtle.Turtle()
t.speed(5)
turtle.colormode(255)

# 绘制爱心并实现颜色渐变
def draw_heart_and_gradient():
    for angle in range(0, 360):
        r = 150 - 150 * math.sin(math.radians(angle))
        x = r * math.cos(math.radians(angle))
        y = r * math.sin(math.radians(angle))
        t.penup()
        t.goto(x, y)
        t.pendown()
        # 设置颜色渐变,这里根据角度调整 RGB 值
        t.color(int(255 * (angle / 360)), int(150 * (angle / 360)), int(200 * (angle / 360)))
        t.begin_fill()
        t.circle(5)
        t.end_fill()

draw_heart_and_gradient()

turtle.done()
运行思路
  • 导入必要的模块:

    • turtle模块用于图形绘制。
    • math模块用于数学计算,这里主要用于角度和弧度的转换以及三角函数的计算。
  • 设置画笔和颜色模式:

    • 创建一个turtle画笔对象t
    • 设置画笔速度为5,这个速度值可以控制画笔移动的快慢,数值越大速度越快。
    • 使用turtle.colormode(255)设置颜色模式为255模式,这意味着可以使用 0 到 255 的整数值来表示 RGB 颜色通道的值。
  • 定义绘制爱心并实现颜色渐变的函数:

    • draw_heart_and_gradient函数用于绘制带有颜色渐变效果的爱心。
    • 使用一个循环遍历从 0 到 360 度的角度范围:
      • 对于每个角度,首先根据心形曲线的数学公式r = 150 - 150 * math.sin(math.radians(angle))计算出当前角度对应的半径r。这里使用了math.sin函数来计算正弦值,并且通过math.radians(angle)将角度从度转换为弧度,因为三角函数在 Python 的math模块中通常接受弧度作为参数。
      • 接着,通过x = r * math.cos(math.radians(angle))y = r * math.sin(math.radians(angle))计算出当前角度对应的坐标(x, y)。这里使用了三角函数math.cosmath.sin来计算横坐标和纵坐标。
      • 然后,抬起画笔t.penup(),移动到计算出的坐标位置t.goto(x, y),再放下画笔t.pendown()
      • 根据当前角度调整 RGB 值来设置画笔颜色。具体来说,使用t.color(int(255 * (angle / 360)), int(150 * (angle / 360)), int(200 * (angle / 360)))。这里通过将角度与特定的数值进行计算,得到不同角度下的 RGB 值,从而实现颜色渐变效果。
      • 开始填充图形t.begin_fill(),画一个半径为 5 的圆t.circle(5),这个圆将作为爱心的一部分,最后结束填充t.end_fill()
  • 调用绘制函数:

    • 调用draw_heart_and_gradient()函数开始绘制带有颜色渐变的爱心。
  • 保持窗口打开:

    • 使用turtle.done()使turtle绘图窗口保持打开状态,等待用户手动关闭窗口。这样用户可以查看绘制好的图形。
二、JavaScript 使用 canvas API
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
</head>

<body>
    <canvas id="myCanvas" width="500" height="500"></canvas>
    <script>
        const canvas = document.getElementById('myCanvas');
        const ctx = canvas.getContext('2d');

        // 绘制爱心并实现颜色渐变
        function drawHeartAndGradient() {
            // 遍历 0 到 360 度
            for (let angle = 0; angle < 360; angle++) {
                // 根据心形曲线公式计算半径
                const r = 150 - 150 * Math.sin(angle * (Math.PI / 180));
                // 计算横坐标
                const x = r * Math.cos(angle * (Math.PI / 180));
                // 计算纵坐标
                const y = r * Math.sin(angle * (Math.PI / 180));
                // 设置颜色渐变,这里根据角度调整 RGB 值
                ctx.fillStyle = `rgb(${255 * (angle / 360)}, ${150 * (angle / 360)}, ${200 * (angle / 360)})`;
                ctx.beginPath();
                // 在指定位置画一个小圆点作为爱心的一部分
                ctx.arc(x + canvas.width / 2, y + canvas.height / 2, 5, 0, 2 * Math.PI);
                ctx.fill();
            }
        }

        drawHeartAndGradient();
    </script>
</body>

</html>
运行思路
  • 在 HTML 文件中创建一个 <canvas> 元素,并通过 document.getElementById 获取到这个元素的引用,同时获取其 2D 绘图上下文 ctx
  • 定义一个函数 drawHeartAndGradient
    • 在这个函数中,使用一个循环遍历从 0 到 360 的角度。
    • 对于每个角度,根据心形曲线公式 const r = 150 - 150 * Math.sin(angle * (Math.PI / 180)) 计算出半径 r
    • 然后通过 const x = r * Math.cos(angle * (Math.PI / 180))  const y = r * Math.sin(angle * (Math.PI / 180)) 计算出该角度对应的坐标 (x, y)
    • 根据当前角度计算颜色的 RGB 值,设置为填充样式 ctx.fillStyle = rgb(${255 * (angle / 360)}, ${150 * (angle / 360)}, ${200 * (angle / 360)})`
    • 开始路径,在指定位置画一个半径为 5 的圆 ctx.arc(x + canvas.width / 2, y + canvas.height / 2, 5, 0, 2 * Math.PI),然后填充这个圆。
  • 调用 drawHeartAndGradient 函数开始绘制爱心和颜色渐变效果。
三、Java 使用 Graphics2D
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

class HeartWithGradient extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        // 遍历 0 到 360 度
        for (int angle = 0; angle < 360; angle++) {
            // 根据心形曲线公式计算半径
            double r = 150 - 150 * Math.sin(Math.toRadians(angle));
            // 计算横坐标
            int x = (int) (r * Math.cos(Math.toRadians(angle)));
            // 计算纵坐标
            int y = (int) (r * Math.sin(Math.toRadians(angle)));
            // 设置颜色渐变,这里根据角度调整 RGB 值
            g2d.setColor(new Color((int) (255 * (angle / 360)), (int) (150 * (angle / 360)), (int) (200 * (angle / 360))));
            // 在指定位置画一个小圆点作为爱心的一部分
            g2d.fill(new Ellipse2D.Double(x + getWidth() / 2 - 5, y + getHeight() / 2 - 5, 10, 10));
        }
    }
}

public class HeartGradientApp {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Heart with Gradient");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new HeartWithGradient());
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}
运行思路
  • 定义一个自定义面板类 HeartWithGradient,继承自 JPanel
  •  HeartWithGradient 类的 paintComponent 方法中,获取 Graphics2D 对象 g2d
    • 使用一个循环遍历从 0 到 360 的角度。
    • 对于每个角度,根据心形曲线公式 double r = 150 - 150 * Math.sin(Math.toRadians(angle)) 计算出半径 r
    • 然后通过 int x = (int) (r * Math.cos(Math.toRadians(angle)));  int y = (int) (r * Math.sin(Math.toRadians(angle))); 计算出该角度对应的坐标 (x, y)
    • 根据当前角度计算颜色的 RGB 值,创建一个新的 Color 对象 g2d.setColor(new Color((int) (255 * (angle / 360)), (int) (150 * (angle / 360)), (int) (200 * (angle / 360))));
    • 在指定位置画一个半径为 5 的椭圆 g2d.fill(new Ellipse2D.Double(x + getWidth() / 2 - 5, y + getHeight() / 2 - 5, 10, 10))
  •  main 方法中,创建一个 JFrame 对象,设置标题、关闭行为、大小等属性。
  •  HeartWithGradient 实例添加到 JFrame 中,并使 JFrame 可见。

Python其它绘画方式

第一种

import random
from math import sin, cos, pi, log
from tkinter import *

CANVAS_WIDTH = 640  # 画布的宽
CANVAS_HEIGHT = 640  # 画布的高
CANVAS_CENTER_X = CANVAS_WIDTH / 2  # 画布中心的X轴坐标
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2  # 画布中心的Y轴坐标
IMAGE_ENLARGE = 11  # 放大比例
HEART_COLOR = "#e77c8e"  # 心的颜色#ff7171


def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):
    """
    “爱心函数生成器”
    :param shrink_ratio: 放大比例
    :param t: 参数
    :return: 坐标
    """
    # 基础函数
    x = 16 * (sin(t) ** 3)
    y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))

    # 放大
    x *= shrink_ratio
    y *= shrink_ratio

    # 移到画布中央
    x += CANVAS_CENTER_X
    y += CANVAS_CENTER_Y

    return int(x), int(y)


def scatter_inside(x, y, beta=0.15):
    """
    随机内部扩散
    :param x: 原x
    :param y: 原y
    :param beta: 强度
    :return: 新坐标
    """
    ratio_x = - beta * log(random.random())
    ratio_y = - beta * log(random.random())

    dx = ratio_x * (x - CANVAS_CENTER_X)
    dy = ratio_y * (y - CANVAS_CENTER_Y)

    return x - dx, y - dy


def shrink(x, y, ratio):
    """
    抖动
    :param x: 原x
    :param y: 原y
    :param ratio: 比例
    :return: 新坐标
    """
    force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.6)  # 这个参数...
    dx = ratio * force * (x - CANVAS_CENTER_X)
    dy = ratio * force * (y - CANVAS_CENTER_Y)
    return x - dx, y - dy


def curve(p):
    """
    自定义曲线函数,调整跳动周期
    :param p: 参数
    :return: 正弦
    """
    # 可以尝试换其他的动态函数,达到更有力量的效果(贝塞尔?)
    return 2 * (3 * sin(4 * p)) / (2 * pi)


class Heart:
    """
    爱心类
    """

    def __init__(self, generate_frame=20):
        self._points = set()  # 原始爱心坐标集合
        self._edge_diffusion_points = set()  # 边缘扩散效果点坐标集合
        self._center_diffusion_points = set()  # 中心扩散效果点坐标集合
        self.all_points = {}  # 每帧动态点坐标
        self.build(2000)

        self.random_halo = 1000

        self.generate_frame = generate_frame
        for frame in range(generate_frame):
            self.calc(frame)

    def build(self, number):
        # 爱心
        for _ in range(number):
            t = random.uniform(0, 2 * pi)  # 随机不到的地方造成爱心有缺口
            x, y = heart_function(t)
            self._points.add((x, y))

        # 爱心内扩散
        for _x, _y in list(self._points):
            for _ in range(3):
                x, y = scatter_inside(_x, _y, 0.05)
                self._edge_diffusion_points.add((x, y))

        # 爱心内再次扩散
        point_list = list(self._points)
        for _ in range(4000):
            x, y = random.choice(point_list)
            x, y = scatter_inside(x, y, 0.17)
            self._center_diffusion_points.add((x, y))

    @staticmethod
    def calc_position(x, y, ratio):
        # 调整缩放比例
        force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.520)  # 魔法参数

        dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1)
        dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1)

        return x - dx, y - dy

    def calc(self, generate_frame):
        ratio = 10 * curve(generate_frame / 10 * pi)  # 圆滑的周期的缩放比例

        halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))
        halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * pi) ** 2))

        all_points = []

        # 光环
        heart_halo_point = set()  # 光环的点坐标集合
        for _ in range(halo_number):
            t = random.uniform(0, 2 * pi)  # 随机不到的地方造成爱心有缺口
            x, y = heart_function(t, shrink_ratio=11.6)  # 魔法参数
            x, y = shrink(x, y, halo_radius)
            if (x, y) not in heart_halo_point:
                # 处理新的点
                heart_halo_point.add((x, y))
                x += random.randint(-14, 14)
                y += random.randint(-14, 14)
                size = random.choice((1, 2, 2))
                all_points.append((x, y, size))

        # 轮廓
        for x, y in self._points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 3)
            all_points.append((x, y, size))

        # 内容
        for x, y in self._edge_diffusion_points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 2)
            all_points.append((x, y, size))

        for x, y in self._center_diffusion_points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 2)
            all_points.append((x, y, size))

        self.all_points[generate_frame] = all_points

    def render(self, render_canvas, render_frame):
        for x, y, size in self.all_points[render_frame % self.generate_frame]:
            render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=HEART_COLOR)


def draw(main: Tk, render_canvas: Canvas, render_heart: Heart, render_frame=0):
    render_canvas.delete('all')
    render_heart.render(render_canvas, render_frame)
    main.after(160, draw, main, render_canvas, render_heart, render_frame + 1)


if __name__ == '__main__':
    root = Tk()  # 一个Tk
    root.title('宝贝爱你哟')  # 将标题设置为'tkinter'
    canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
    canvas.pack()
    heart = Heart()  # 心
    draw(root, canvas, heart)  # 开始画
    root.mainloop()
代码逐行注释
import random
from math import sin, cos, pi, log
from tkinter import *

CANVAS_WIDTH = 640  # 画布的宽
CANVAS_HEIGHT = 640  # 画布的高
CANVAS_CENTER_X = CANVAS_WIDTH / 2  # 画布中心的 X 轴坐标
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2  # 画布中心的 Y 轴坐标
IMAGE_ENLARGE = 11  # 放大比例
HEART_COLOR = "#e77c8e"  # 心的颜色#ff7171


def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):
    """
    “爱心函数生成器”
    :param shrink_ratio: 放大比例
    :param t: 参数
    :return: 坐标
    """
    # 基础函数
    x = 16 * (sin(t) ** 3)
    y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))

    # 放大
    x *= shrink_ratio
    y *= shrink_ratio

    # 移到画布中央
    x += CANVAS_CENTER_X
    y += CANVAS_CENTER_Y

    return int(x), int(y)


def scatter_inside(x, y, beta=0.15):
    """
    随机内部扩散
    :param x: 原 x
    :param y: 原 y
    :param beta: 强度
    :return: 新坐标
    """
    ratio_x = - beta * log(random.random())
    ratio_y = - beta * log(random.random())

    dx = ratio_x * (x - CANVAS_CENTER_X)
    dy = ratio_y * (y - CANVAS_CENTER_Y)

    return x - dx, y - dy


def shrink(x, y, ratio):
    """
    抖动
    :param x: 原 x
    :param y: 原 y
    :param ratio: 比例
    :return: 新坐标
    """
    force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.6)  # 这个参数影响抖动效果
    dx = ratio * force * (x - CANVAS_CENTER_X)
    dy = ratio * force * (y - CANVAS_CENTER_Y)
    return x - dx, y - dy


def curve(p):
    """
    自定义曲线函数,调整跳动周期
    :param p: 参数
    :return: 正弦
    """
    # 可以尝试换其他的动态函数,达到更有力量的效果(贝塞尔?)
    return 2 * (3 * sin(4 * p)) / (2 * pi)


class Heart:
    """
    爱心类
    """

    def __init__(self, generate_frame=20):
        self._points = set()  # 原始爱心坐标集合
        self._edge_diffusion_points = set()  # 边缘扩散效果点坐标集合
        self._center_diffusion_points = set()  # 中心扩散效果点坐标集合
        self.all_points = {}  # 每帧动态点坐标
        self.build(2000)

        self.random_halo = 1000

        self.generate_frame = generate_frame
        for frame in range(generate_frame):
            self.calc(frame)

    def build(self, number):
        # 爱心
        for _ in range(number):
            t = random.uniform(0, 2 * pi)  # 随机不到的地方造成爱心有缺口
            x, y = heart_function(t)
            self._points.add((x, y))

        # 爱心内扩散
        for _x, _y in list(self._points):
            for _ in range(3):
                x, y = scatter_inside(_x, _y, 0.05)
                self._edge_diffusion_points.add((x, y))

        # 爱心内再次扩散
        point_list = list(self._points)
        for _ in range(4000):
            x, y = random.choice(point_list)
            x, y = scatter_inside(x, y, 0.17)
            self._center_diffusion_points.add((x, y))

    @staticmethod
    def calc_position(x, y, ratio):
        # 调整缩放比例
        force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.520)  # 魔法参数,影响点的位置调整
        dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1)
        dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1)
        return x - dx, y - dy

    def calc(self, generate_frame):
        ratio = 10 * curve(generate_frame / 10 * pi)  # 圆滑的周期的缩放比例

        halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))
        halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * pi) ** 2))

        all_points = []

        # 光环
        heart_halo_point = set()  # 光环的点坐标集合
        for _ in range(halo_number):
            t = random.uniform(0, 2 * pi)  # 随机不到的地方造成爱心有缺口
            x, y = heart_function(t, shrink_ratio=11.6)  # 魔法参数
            x, y = shrink(x, y, halo_radius)
            if (x, y) not in heart_halo_point:
                # 处理新的点
                heart_halo_point.add((x, y))
                x += random.randint(-14, 14)
                y += random.randint(-14, 14)
                size = random.choice((1, 2, 2))
                all_points.append((x, y, size))

        # 轮廓
        for x, y in self._points:
            x, y = self.calc_position(x, 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/910243.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

部署stable-diffusion3.5 大模型,文生图

UI 使用推荐的ComfyUI&#xff0c;GitHub 地址&#xff0c;huggingface 需要注册登录&#xff0c;需要下载的文件下面有说明 Dockerfile 文件如下&#xff1a; FROM nvidia/cuda:12.4.0-base-ubuntu22.04 RUN apt-get update && apt-get install python3 pip git --n…

glibc 内存分配与释放机制详解

作者&#xff1a;来自 vivo 互联网存储团队- Wang Yuzhi 本文以一次线上故障为基础介绍了使用 glibc 进行内存管理可能碰到问题&#xff0c;进而对库中内存分配与释放机制进行分析&#xff0c;最后提供了相应问题的解决方案。 一、引言 内存对象的分配与释放一直是后端开发人…

SpringBoot框架在城镇住房保障中的应用

3系统分析 3.1可行性分析 通过对本城镇保障性住房管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本城镇保障性住房管理系统采用SSM框架&#xff0c;JA…

Openlayers高级交互(20/20):超级数据聚合,页面不再混乱

本示例在vue+openlayers中使用cluster生成聚合数据的效果。在OpenLayers中实现点聚合(clustering)是一个常见的需求,特别是在处理大量地理数据点时。聚合可以提高地图的性能并减少视觉上的混乱。 一、示例效果图 专栏名称内容介绍Openlayers基础实战 (72篇)专栏提供73篇文…

内网渗透-信息收集篇

通过webshell或其他方式拿下一台机器&#xff0c;并且存在内网环境&#xff0c;这个时候就在准备进行内网渗透&#xff0c;而在内网渗透之前需要对本地机器进行信息收集&#xff0c;才能够更好的进行内网渗透。 目录 Windows本地基础信息收集 权限查看 判断域存在 查看防火…

诗林工作室(编号:mb0005)分享:HTML模版Paxton,一款自适应响应式图集、博客设计开发模板

这是来自国外一款HTML网页模板&#xff0c;适合Web开发人员做前端站点设计参考使用。全站模版倾向于图集、博客等多行业的平台模版开发。此模版适合各大CMS的主题模版开发参考&#xff0c;如常见的Wordpress主题开发、Z-Blog模板开发、Typecho模板开发、DiscuzX模板开发、Jooml…

SSLHandshakeException错误解决方案

1、错误提示 调用Http工具报如下异常信息&#xff1a; cn.hutool.core.io.IORuntimeException: SSLHandshakeException: Received fatal alert: handshake_failure2、查询问题 一开始我以为是代码bug&#xff0c;网络bug甚至是配置环境未生效&#xff0c;找了一大圈&#xf…

VBA07-方法

一、方法的定义 方法指对象所能执行的动作&#xff0c;它是一个动词。 二、方法的表达方式 三、关于工作簿的方法操作 3-1、新增一个工作簿 示例1&#xff1a; 此时&#xff0c;新增的工作簿的名字是系统默认的。 示例2&#xff1a; 【注意】&#xff1a; 当你尝试将工作簿…

MyBatis3-获取参数值的方式、查询功能及特殊SQL执行

目录 准备工作 获取参数值的方式&#xff08;重点&#xff09; 查询功能 查询一个实体类对象 查询一个list集合 查询单个数据 查询一条数据为map集合 查询多条数据为map集合 特殊SQL执行 模糊查询 批量删除 动态设置表名 添加功能获取自增的主键 准备工作 模块My…

构建基于 DCGM-Exporter, Node exporter,PROMETHEUS 和 GRAFANA 构建算力监控系统

目录 引言工具作用概述DCGM-ExporterNode exporterPROMETHEUSGRAFANA小结 部署单容器DCGM-ExporterNode exporterPROMETHEUSGRAFANANode exporterDCGM-Exporter 多容器Node exporterDCGM-ExporterDocker Compose 参考 引言 本文的是适用对象&#xff0c;是希望通过完全基于Doc…

基因组学与个性化健康:精准医疗的未来方向

基因组学&#xff08;Genomics&#xff09;是指对基因组&#xff0c;即一个生物体的全部基因和遗传信息进行分析和研究的科学&#xff0c;旨在探索基因在生物体中的功能、相互作用及其对健康和疾病的影响。个性化健康&#xff08;Personalized Health&#xff09;则是基于个体的…

阅读个位数?1分钟学会用AI做爆款,轻松涨粉不是梦

从去年开始&#xff0c;AI造就的视觉艺术就在各个平台上疯狂蔓延&#xff0c;人类用AI一年生成的内容&#xff0c;比过往几千年加起来都多。 网络上铺天盖地都是搞AI&#xff0c;但大部分人真的是在搞AI吗&#xff1f;并不尽然&#xff0c;大部分人只是想用AI搞钱。 更多实操…

发现 API 的 5 种方法

在处理目标时&#xff0c;最值得测试的部分是其 API。API 是动态的&#xff0c;它们比应用程序的其他部分更新得更频繁&#xff0c;并且负责许多后端繁重的工作。在现代应用程序中&#xff0c;我们通常会看到 REST API&#xff0c;但也会看到其他形式&#xff0c;例如 GraphQL …

Netty 如何自动探测内存泄露的发生

本文基于 Netty 4.1.112.Final 版本进行讨论 本文是 Netty 内存管理系列的最后一篇文章&#xff0c;在第一篇文章 《聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现》 中&#xff0c;笔者以 UnpooledByteBuf 为例&#xff0c;从整个内存管理的外围对 ByteBuf 的整个设计体系…

51单片机教程(六)- LED流水灯

1 项目分析 基于点亮LED灯、LED灯闪烁&#xff0c;扩展到构成最简单、花样流水灯。 2 技术准备 1 流水灯硬件及原理图 流水灯是由多个LED灯组成的 2 C语言知识点 数组 数组声明&#xff1a;长度不可变 数据类型 数组名称[长度n] // 整数型默认为0&#xff0c;小数型默认…

基础算法——排序算法(冒泡排序,选择排序,堆排序,插入排序,希尔排序,归并排序,快速排序,计数排序,桶排序,基数排序,Java排序)

1.概述 比较排序算法 算法最好最坏平均空间稳定思想注意事项冒泡O(n)O( n 2 n^2 n2)O( n 2 n^2 n2)O(1)Y比较最好情况需要额外判断选择O( n 2 n^2 n2)O( n 2 n^2 n2)O( n 2 n^2 n2)O(1)N比较交换次数一般少于冒泡堆O( n l o g n nlogn nlogn)O( n l o g n nlogn nlogn)O( n l…

SpringBoot基础系列学习(四):Thymeleaf模板

文章目录 一丶什么是模板引擎二丶Thymeleaf 介绍三丶使用引入依赖代码html页面响应 一丶什么是模板引擎 模板引擎是一种将数据和模板结合起来生成最终结果的工具&#xff0c;它将一个模板和一个数据对象作为输入&#xff0c;通过模板解析和渲染生成最终的结果。通俗地说&#…

模块化开发 webpack

模块化开发 & webpack 1、模块化开发 & webpack1.1 webpack 执行过程1.1.1 初始化1.1.2 编译1.1.3 输出 2.1 webpack 基础配置2.1.1 Entry2.1.1.1 context2.1.1.2 Entry类型 2.1.2 output2.1.2.1 filename2.1.2.2 publicPath2.1.2.3 path2.1.2.4 libraryTarget 和 libr…

Spring WebFlux 核心原理(2-3)

1、Project Reactor 高级 1.1、响应式流的生命周期 要理解多线程的工作原理以及 Reactor 中实现的各种内部优化&#xff0c;首先必须了解 Reactor 中响应式类型的生命周期。 1.1.1、组装时 流生命周期的第一部分是组装时&#xff08;assembly-time&#xff09;。 Reactor 提供…

LabVIEW编程过程中为什么会出现bug?

在LabVIEW编程过程中&#xff0c;Bug的产生往往源自多方面原因。以下从具体的案例角度分析一些常见的Bug成因和调试方法&#xff0c;以便更好地理解和预防这些问题。 ​ 1. 数据流错误 案例&#xff1a;在一个LabVIEW程序中&#xff0c;多个计算节点依赖相同的输入数据&#…