chiark / gitweb /
simplex wip: use gsl_vector_get for X, for abandonment
[moebius3.git] / bezier.py
1 # Copied from
2 #   /usr/lib/python2.7/dist-packages/matplotlib/bezier.py
3 # in Debian's python-matplotlib 2.0.0+dfsg1-2 (amd64)
4 # and trimmed to have only BezierSegment
5
6 # Copyright: Copyright (c) 2002 - 2012 John Hunter, Darren Dale, Eric Firing, Michael Droettboom and the matplotlib development team; 2012 - 2016 The matplotlib development team
7 #
8 # 1. This LICENSE AGREEMENT is between the Matplotlib Development Team
9 # ("MDT"), and the Individual or Organization ("Licensee") accessing and
10 # otherwise using matplotlib software in source or binary form and its
11 # associated documentation.
12 # .
13 # 2. Subject to the terms and conditions of this License Agreement, MDT
14 # hereby grants Licensee a nonexclusive, royalty-free, world-wide license
15 # to reproduce, analyze, test, perform and/or display publicly, prepare
16 # derivative works, distribute, and otherwise use matplotlib
17 # alone or in any derivative version, provided, however, that MDT's
18 # License Agreement and MDT's notice of copyright, i.e., "Copyright (c)
19 # 2012- Matplotlib Development Team; All Rights Reserved" are retained in
20 # matplotlib  alone or in any derivative version prepared by
21 # Licensee.
22 # .
23 # 3. In the event Licensee prepares a derivative work that is based on or
24 # incorporates matplotlib or any part thereof, and wants to
25 # make the derivative work available to others as provided herein, then
26 # Licensee hereby agrees to include in any such work a brief summary of
27 # the changes made to matplotlib .
28 # .
29 # 4. MDT is making matplotlib available to Licensee on an "AS
30 # IS" basis.  MDT MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
31 # IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, MDT MAKES NO AND
32 # DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
33 # FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB
34 # WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
35 # .
36 # 5. MDT SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB
37 #  FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
38 # LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING
39 # MATPLOTLIB , OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF
40 # THE POSSIBILITY THEREOF.
41 # .
42 # 6. This License Agreement will automatically terminate upon a material
43 # breach of its terms and conditions.
44 # .
45 # 7. Nothing in this License Agreement shall be deemed to create any
46 # relationship of agency, partnership, or joint venture between MDT and
47 # Licensee.  This License Agreement does not grant permission to use MDT
48 # trademarks or trade name in a trademark sense to endorse or promote
49 # products or services of Licensee, or any third party.
50 # .
51 # 8. By copying, installing or otherwise using matplotlib ,
52 # Licensee agrees to be bound by the terms and conditions of this License
53 # Agreement.
54
55 import six
56 import numpy as np
57 import warnings
58
59 class BezierSegment(object):
60     """
61     A simple class of a N-dimensional bezier segment
62     """
63
64     # Higher order bezier lines can be supported by simplying adding
65     # corresponding values.
66     _binom_coeff = {1: np.array([1., 1.]),
67                     2: np.array([1., 2., 1.]),
68                     3: np.array([1., 3., 3., 1.])}
69
70     def __init__(self, control_points):
71         """
72         *control_points* : location of contol points. It needs have a
73          shpae of n * D, where n is the order of the bezier line
74          and D is the dimension (the length of each control point
75          tuple). 1<= n <= 3 is supported.
76         """
77         _o = len(control_points)
78         dim = len(control_points[0])
79         self._orders = np.arange(_o)
80         _coeff = BezierSegment._binom_coeff[_o - 1]
81
82         _control_points = np.asarray(control_points)
83         xyz = [_control_points[:, i] for i in range(0, dim)]
84
85         self._pxyz = [xx * _coeff for xx in xyz]
86
87     def point_at_t(self, t):
88         "evaluate a point at t"
89         one_minus_t_powers = np.power(1. - t, self._orders)[::-1]
90         t_powers = np.power(t, self._orders)
91
92         tt = one_minus_t_powers * t_powers
93         _xyz = [sum(tt * px) for px in self._pxyz]
94
95         return tuple(_xyz)