python高级练习题:贝塞尔曲线【难度:4级】:
贝塞尔曲线
当使用矢量图形中描述了一种形状,其轮廓通常被描述为线性,二次,和三次贝塞尔曲线的序列.您可以在维基百科阅读贝塞尔曲线.
你不需要知道很多关于贝塞尔曲线来解决这个习题.只知道线性方程,二次和三次曲线(分别)给出:
1.P(T)=(1 - T)* P0 + T * P1
2.P(T)=(1 - T)** 2 * P0 + 2 *(1 - T)*T* P1 + T ** 2 * P2
3.P(T)=(1 - T)** 3 * P0 + 3 *(1 - T)** 2 *T* P1 + 3 *(1 - T)*T** 2 * P2 + 吨** 3 * P3
点P0
,P1
,P2
,P3
被称为曲线的控制点,和t
是一个变量,该变量,从0
取值为1
时,会引起P(吨)
跟踪的曲线.
这应该足以实现point_at(T)你要实现的类
方法.
为了实现sub_segment(吨)
方法,参见,特别是对构建上面引用的维基百科文章的Bézier曲线段.
该部分显示的贝塞尔曲线如何成长的动画.该动画被显示越来越长的子部分,因此,示出的子部分是如何构造的.如果你在四曲线动画仔细观察,你可以看到如何控制点从开始都在P0分别为P0,P1和P2结束了移动.现在仔细一看,在三次曲线的动画.看到不断增长的小节开始在P0的控制点,并在P0,P1,P2和P3结束.无需读什么,只是看看.在引用款到底有到德卡斯特里奥算法,您可能发现有用的链接,但我不会去那里.只要仔细看动画.
在这习题,你被要求实现一个类为每个线性,二次和三次贝塞尔曲线.这些类必须扩展以下抽象基类,并实现抽象方法:
的Python
从ABC进口ABCMeta,abstractmethod
类链段(元类= ABCMeta):
@属性
@abstractmethod
高清control_points(个体经营):
通过
@abstractmethod
DEF point_at(个体,T):
通过
@abstractmethod
DEF sub_segment(个体,T):
通过
control_points
是返回定义曲线的点的坐标的属性.由于线性曲线具有两个控制点(该段的开始和结束),control_points
将持有4个浮点,这是x轴和随后的x和的y坐标中的第一点的y坐标第二点.对于二次和三次曲线分别有6个8控制点.
该方法point_at(吨)
应返回方程对于曲线中插入t
时获得的点.此方法将在间隔``t的值进行测试[0,1]
只(尽管这是可能的外推曲线).
该方法sub_segment(T_0)
应该返回开始于第一点和在由point_at(T_0)返回的点处结束
和如下,该方法是在调用否则该对象的曲线的曲线.例如,如果quad
是二次曲线,然后quad.sub_segment(T_0)
是开始于quad
的第一点和在quad.point_at(T_0)结束二次曲线
和如下四
的曲线.更确切地说,
quad.point_at(T_0 * T)== quad.sub_segment(T_0).point_at(t)的
在间隔``t的所有值[0,1]
.
编程目标:
from abc import ABCMeta, abstractmethod
class Segment(metaclass=ABCMeta):
@property
@abstractmethod
def control_points(self):
pass
@abstractmethod
def point_at(self, t):
pass
@abstractmethod
pass
class Line(Segment):
def __init__(self, *coords):
self._control_points = coords
测试样例:
Test.describe('Full test suite')
Test.it('Initialization')
line = Line(1, 2, 3, 4)
Test.expect(isinstance(line, Segment))
Test.expect(isinstance(line, Line))
quad = Quad(1, 2, 3, 4, 5, 6)
cubic = Cubic(1, 2, 3, 4, 5, 6, 7, 8)
Test.expect(isinstance(cubic, Segment))
Test.expect(isinstance(cubic, Cubic))
Test.it('Control points')
18