python - matplotlib:如何绘制一个带有随机 x 变形的圆?
问题描述
我需要画一个不完美的圆,我的意思是在圆上的某些点,半径需要改变(更大或更小)以产生所需的变形。
例如,此图像显示了一个具有 1 个单一变形的圆:
变形的数量是随机的,位置也是随机的。
我正在使用下面的代码来绘制一个正常的圆圈:
import numpy as np
import matplotlib.pyplot as plt
theta = np.linspace(0, 2*np.pi, 200)
radius = 0.4
a = radius * np.cos(theta)
b = radius * np.sin(theta)
figure, axes = plt.subplots(1)
axes.plot(a, b)
axes.set_aspect(1)
plt.show()
你有什么想法我怎么能做到这一点?
解决方案
使半径取决于 theta,我们可以有一个函数f
:
- 当距离一个角度超过 2 步时
theta1
:f(t) = 1
- 在 1 和 2 步之外
f(1) = f(2) = 1
- 处有
theta1
一个变形f(0) = k
,对于一些k
- 在 0 和 2 处,变形的切线应为零
- 对于负数
t
,我们可以使用f
绝对值
如果f
是多项式,它可能是 4 次,所以f = a*t**4 + b*t**3 + c*t**2 + d*t + e
. 符号数学库 sympy 可以在给定的约束条件下为这些参数找到合适的值。
from sympy import Eq, solve
from sympy.abc import a, b, c, d, e, t, k
f = a * t ** 4 + b * t ** 3 + c * t ** 2 + d * t + e
eq1 = Eq(f.subs(t, 0), k)
eq2 = Eq(f.subs(t, 1), 1)
eq3 = Eq(f.subs(t, 2), 1)
eq4 = Eq(f.diff(t).subs(t, 0), 0)
eq5 = Eq(f.diff(t).subs(t, 2), 0)
sol = solve([eq1, eq2, eq3, eq4, eq5], (a, b, c, d, e))
这会生成(经过一些重写),以下表达式f
:
k + (2 * t ** 2 - 9 * t + 11) * t ** 2 * (1 - k) / 4
现在,使用这个函数来绘制变形的圆:
import matplotlib.pyplot as plt
import numpy as np
theta = np.linspace(0, 2 * np.pi)
k = 0.8
theta1 = 80 * np.pi / 180 # a deformation at theta 80 degrees
alpha = 36 * np.pi / 180 # have a special point every 36 degrees (10 on the circle)
th = theta - theta1 # the difference between the angles, still needs to be careful to make this difference symmetrical to zero
t = np.abs(np.where(th < np.pi, th, th - 2 * np.pi)) / alpha # use absolute value and let alpha represent a step of 1
r = np.where(t > 2, 1, k + (2 * t ** 2 - 9 * t + 11) * t ** 2 * (1 - k) / 4) # the deformed radius
plt.plot(np.cos(theta), np.sin(theta), ':r')
plt.plot(r * np.cos(theta), r * np.sin(theta), '-b')
plt.fill(r * np.cos(theta), r * np.sin(theta), color='blue', alpha=0.2)
for i in range(-5, 5):
plt.plot(np.cos(theta1 + i * alpha), np.sin(theta1 + i * alpha), 'xk')
plt.axis('equal')
plt.show()
推荐阅读
- crystal-reports - Crystal Reprots 2013 迁移到新服务器
- ffmpeg - 带 Alpha 通道的自适应视频编码
- r - 将多个excel文件作为一个数据框/表读取
- c# - Angular 9 http.delete 返回不支持的媒体 415
- c# - 使用 HoloLens 2 获取空间坐标系的正确方法
- android - 在 Room Kotlin 中插入改造响应
- asp.net-core - 如何在 ASP.Net Core 应用程序中向 Azure AD 身份验证用户添加自定义声明?
- android - 在 Android Studio 中运行单元测试时,类覆盖率和行覆盖率有什么区别?
- python - 如何从字典Python中获取值中的所有数组项
- datatables - jquery datatable ajax附加不需要的查询参数