简体   繁体   English

matplotlib:如何绘制具有随机 x 变形的圆?

[英]matplotlib : How can I draw a circle with random x deformations?

I need to draw a circle that's not perfect, I mean at some points on the circle the radius needs to change (be greater or lower) in order to cause the desired deformation.我需要画一个不完美的圆,我的意思是在圆上的某些点,半径需要改变(更大或更小)以产生所需的变形。

This image for instance shows a circle with 1 single deformation:例如,此图像显示了一个具有 1 个单一变形的圆:

在此处输入图像描述

The number of the deformations is random and the positions also.变形的数量是随机的,位置也是随机的。

I am using the code below to draw a normal circle:我正在使用下面的代码来绘制一个正常的圆圈:

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()

Do you have any ideas how can I achieve this?你有什么想法我怎么能做到这一点?

Making the radius depend on theta, we could have a function f such that:使半径取决于 theta,我们可以有一个 function f使得:

  • When further than 2 steps away from an angle theta1 : f(t) = 1当距离角度theta1超过 2 步时: f(t) = 1
  • At 1 and 2 steps away f(1) = f(2) = 1在 1 和 2 步远f(1) = f(2) = 1
  • At theta1 there is a deformation such that f(0) = k , for some ktheta1有一个变形使得f(0) = k ,对于一些k
  • At 0 and 2, the tangent to the deformation should be zero在 0 和 2 处,变形的切线应为零
  • For negative t , we can use f on the absolute value对于负t ,我们可以在绝对值上使用f

If f would be a polynomial, it could be of degree 4, so f = a*t**4 + b*t**3 + c*t**2 + d*t + e .如果f是多项式,它可能是 4 次,所以f = a*t**4 + b*t**3 + c*t**2 + d*t + e The symbolic math library, sympy, can find suitable values for these parameters with the given constraints.符号数学库 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))

This generates (after some rewriting), the following expression for f :这会生成(经过一些重写后) f的以下表达式:

k + (2 * t ** 2 - 9 * t + 11) * t ** 2 * (1 - k) / 4

Now, use this function to draw the deformed circle:现在,使用这个 function 来绘制变形圆:

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()

结果图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM