【发布时间】:2014-04-06 22:26:40
【问题描述】:
我一直在尝试使用计算机绘制一些hypotrochoids,但我遇到了一些问题。对于那些不熟悉的人,次摆线的参数方程是:
x(theta) = (R - r)cos(theta) + d*cos((R-r)/r*theta)
和
y(theta) = (R - r)sin(theta) - d*sin((R-r)/r*theta)
维基百科上对下摆线的定义可以进一步解释:
下摆线是一个轮盘赌,由一个连接到一个圆的点追踪 半径 r 在半径为 R 的固定圆内滚动, 其中该点距内部中心的距离为 d 圈子。
因此,值为r = d = 1 和R = 3 的下摆线应该如下所示:
但这肯定不是我最终使用我的计算方法的结果。我的下摆线(具有相同的值)看起来像这样:
由于 x 和 y 值是由 x 和 y 在角度 theta 的函数确定的,我假设我可以简单地循环 theta 从 0 到 2pi 的值,并在某个特定位置分别计算 x 和 y 值间隔,然后以极坐标形式绘制坐标(r**2 = x**2 + y**2),但我想我想错了。也许我的公式是错误的,但我刚刚在math stackexchange 与几个人一起检查过,但我们无法弄清楚出了什么问题。如果我的方法有误,应该使用什么方法来计算下摆线?
代码如下:
class _BaseCurve(event.EventAware):
# This is a basic curve class from which all other curves inherit from (as
# you will see below with the Hypotrochoid class). Basically what happens is
# each new curve class must implement a function (relation) to calculate the
# radius of the equation at each angle interval, then plots the equation in
# other code elsewhere.
def __init__(self, radius, init_angle, end_angle, speed, acceleration, *args, **kwargs):
# Initialize geometric data...
self.radius = radius
# Initialize curve start and end angles...
self.init_angle = init_angle
self.end_angle = end_angle
# Initialize time-based curve attributes...
self.speed = speed
self.accel = acceleration
self.current_pos = 0
# Initialize defaults...
self.max_speed = inf
self.min_speed = neginf
self.args = args
self.kwargs = kwargs
def set_max_speed(self, speed):
"""Set the maximum speed the path can achieve."""
if speed < self.min_speed:
errmsg = "Max speed cannot be less than min speed."
raise ValueError(errmsg)
self.max_speed = speed
def set_min_speed(self, speed):
"""Set the minimum speed the path can achieve."""
if speed > self.max_speed:
errmsg = "Min speed cannot be greater than max speed."
raise ValueError(errmsg)
self.max_speed = speed
def set_acceleration(self, acceleration):
"""Set a new acceleration for the path."""
self.accel = acceleration
def move(self):
"""Progress the path forward one step.
The amount progressed each time (curve).move is called
depends on the path's speed parameter and the distance
(i.e. angle_difference) it has to travel. The calculation
is as follows:
angle = angle_difference * current_position + init_angle
Where current_position is the position incremented by the
set speed in (curve).move().
"""
self.current_pos += self.speed
if self.accel != 1:
new_speed = self.speed * self.accel
self.speed = max(min(new_speed, self.max_speed), self.min_speed)
def angle(self):
"""Return the angle of the curve at the current position."""
return self.angle_difference * self.current_pos + self.init_angle
def relation(self):
"""Return the relationship of the current angle to the radius.
This is a blank function left to be filled in by subclasses of
_BasicCurve. The return value for this function must be a function
(or lambda expression), of which that function's return value should
be the radius of the curve at the current position. The parameters of
the return equation should be as follows:
(Assuming `r` is the function representing the relation):
radius = r(current_angle, *args, **kwargs)
Where *args and **kwargs are the additional *args and **kwargs specified
upon initializing the curve.
"""
return NotImplemented
def position(self):
"""Calculate the position on the curve at the current angle.
The return value of this function is the coordinate in polar
form. To view the coordinate in cartesian form, use the
`to_cartesian` function. # Ignore the `to_cartesian` function in this code snippet, it simply converts polar to cartesian coordinates.
NOTE: This function requires self.relation to be implemented.
"""
r = self.relation()
theta = self.current_angle
args = self.args
kwargs = self.kwargs
radius = self.radius*r(theta, *args, **kwargs)
return radius, theta
@property
def angle_difference(self):
"""The difference between the start and end angles specified."""
return (self.end_angle - self.init_angle)
@property
def current_angle(self):
"""The current angle (specified by self.current_pos)."""
return self.angle_difference * self.current_pos + self.init_angle
Curve = _BaseCurve
class Hypotrochoid(Curve):
def relation(self):
def _relation(theta, r, R, d):
x = (R - r)*math.cos(theta) + d*math.cos((R - r)/r * theta)
y = (R - r)*math.sin(theta) - d*math.sin((R - r)/r * theta)
return (x**2 + y**2)**(1/2)
return _relation
【问题讨论】:
标签: python debugging plot geometry