Skip to content

Instantly share code, notes, and snippets.

@ewjoachim
Created June 1, 2015 15:33
Show Gist options
  • Save ewjoachim/f84823fa9ce6c8486890 to your computer and use it in GitHub Desktop.
Save ewjoachim/f84823fa9ce6c8486890 to your computer and use it in GitHub Desktop.
Bezier
Display the source blob
Display the rendered blob
Raw
{"nbformat_minor": 0, "cells": [{"execution_count": 1, "cell_type": "code", "source": "from collections import namedtuple\n\n\nclass Point(namedtuple(\"BasePoint\", (\"x\", \"y\"))):\n \"\"\"\n This is a 2D point that can be accessed as a tuple or as an object with x and y properties\n \"\"\"\n # We can make this a 3D point just by adding a \"z\" in the definition\n \n # Note : common operations are defined in this class to ease manipulation\n @property\n def point(self):\n # This is for compatibility with BezierPoint\n return self\n \n # Operations\n def __add__(self, other_point):\n \"\"\"\n Handles Point() + Point()\n \"\"\"\n return Point(*(sum(dim) for dim in zip(self, other_point)))\n \n def __mul__(self, scalar):\n \"\"\"\n Handles Point() * scalar\n \"\"\"\n # Point() \n return Point(*(scalar * dim for dim in self))\n \n def __rmul__(self, scalar):\n \"\"\"\n Handles scalar * Point()\n \"\"\"\n return self * scalar\n \n def __sub__(self, other_point):\n \"\"\"\n Handles Point() - Point()\n \"\"\"\n return self + (other_point * -1)\n \n # More complicated operations\n \n def lerp(self, other_point, alpha):\n \"\"\"\n Linear interpolation between 2 points.\n \n >>> p1 = Point(1, 2)\n >>> p2 = Point(3, 4)\n >>> p1.lerp(p2, 0)\n Point(1, 2)\n \n >>> p1.lerp(p2, 1)\n Point(3, 4)\n \n >>> p1.lerp(p2, 0.5)\n Point(2, 3)\n \n \"\"\"\n return self + alpha * (other_point - self)\n\n # display\n \n def __repr__(self):\n return \"{}{}\".format(self.__class__.__name__, tuple(self))", "outputs": [], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 41, "cell_type": "code", "source": "class BezierPoint(object):\n \"\"\"\n Class for a simple Bezier point, which is a point\n and a control point (there's only 1 control point, that's not a cubic bezier)\n \"\"\"\n def __init__(self, point, control_point):\n self.point = point\n self.control_point = control_point\n \n def bezierPoint(self, other_point, alpha):\n \"\"\"\n Returns a point in the bezier curve between 2 points, for a given\n alpha value (0 < alpha < 1)\n \"\"\"\n p1 = self.point.lerp(self.control_point, alpha)\n p2 = self.control_point.lerp(other_point.point, alpha)\n curve_point = p1.lerp(p2, alpha)\n return curve_point\n \n def bezierPoints(self, end_point, steps):\n \"\"\"\n Returns <steps> points on the bezier curve between this point and the end_point\n \"\"\"\n return [self.bezierPoint(end_point, alpha) for alpha in float_range(step=1. / steps, include_end=True)]", "outputs": [], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 42, "cell_type": "code", "source": "start_point = BezierPoint(Point(1,2), control_point=Point(1, 7))\nend_point = Point(3, 2)\nsteps = 100", "outputs": [], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 43, "cell_type": "code", "source": "def float_range(start=0, end=1, step=0.1, include_end=False):\n while start < end:\n yield start\n start += step\n if include_end:\n yield end", "outputs": [], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 44, "cell_type": "code", "source": "curve = start_point.bezierPoints(end_point, steps)", "outputs": [], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 45, "cell_type": "code", "source": "import matplotlib.pyplot as plt\n%matplotlib inline ", "outputs": [], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 46, "cell_type": "code", "source": "def plot_curve(curve):\n plt.plot([e.x for e in curve], [e.y for e in curve])\n \nplot_curve(curve)", "outputs": [{"output_type": "display_data", "data": {"image/png": "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\n", "text/plain": "<matplotlib.figure.Figure at 0x108600e10>"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 47, "cell_type": "code", "source": "def double_iterator(iterable):\n it = iter(iterable)\n old_val = next(it)\n val = next(it)\n while True:\n yield (old_val, val)\n old_val, val = val, next(it)", "outputs": [], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 48, "cell_type": "code", "source": "def bezier_curve(points, steps):\n return [\n curve_point\n for point1, point2 in double_iterator(points)\n for curve_point in point1.bezierPoints(point2, steps)\n ]\n ", "outputs": [], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 64, "cell_type": "code", "source": "points = [\n BezierPoint(Point(1, 2), control_point=Point(3, 7)),\n BezierPoint(Point(2, 6), control_point=Point(1, 8)),\n Point(4, 7),\n]\ncurve = bezier_curve(points, steps)", "outputs": [], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": 65, "cell_type": "code", "source": "plot_curve(curve)", "outputs": [{"output_type": "display_data", "data": {"image/png": "iVBORw0KGgoAAAANSUhEUgAAAW0AAAEACAYAAAB4ayemAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGPVJREFUeJzt3XmYXFWdxvHvm42EsImsEmRRUUFFUBBIAg2ELQIODCqi\nyOIoo0jc0BE3YHQcRVREBBk2ERER2XdBaBZFGCQsgjiIGyIJEEggECDLb/64t0mlU91V3V23zr1V\n7+d57tPV3ZWq381Nv31y7lkUEZiZWTWMSl2AmZk1z6FtZlYhDm0zswpxaJuZVYhD28ysQhzaZmYV\n0jC0JR0l6X5J90n6qaQV2lGYmZktb9DQlrQh8GFgy4h4MzAa2L/4sszMrJ4xDb7/DLAQWFHSYmBF\n4NHCqzIzs7oGbWlHxFPAt4G/A/8E5kbE9e0ozMzMlteoe+Q1wCeBDYFXAStJen8b6jIzszoadY+8\nHfhNRMwBkHQRsB1wbt8TJHnxEjOzYYgIDfXPNArtB4EvS5oAvABMA+5oxRtXhaRjIuKY1HUUxedX\nbZ18fp18bjD8Bm+jPu17gB8DdwL35l/+n+G8kZmZjVyjljYRcRxwXBtqMTOzBjwjsrHe1AUUrDd1\nAQXrTV1AwXpTF1Cg3tQFlJFGugmCpOjkPm0zsyIMNzvd0jYzqxCHtplZhTi0zcwqxKFtZlYhDm0z\nswpxaJuZVYhD28ysQhzaZmYV4tA2M6sQh7aZWYU4tM3MKsShbWZWIQ5tM7MKcWibmVWIQ9vMrEIc\n2mZmFeLQNjOrkIZ7RJqlJDEKGAeMzY/anT767/rR//PFwKLaI4IlBZVq1hYObRsxidHAasDqdY6V\ngYk1x0r9Pp8ITCAL5tpw7ns8CngJWJgf/UO3/355fZ8r/7Njao6xEsGyQb6w5vGLwAs1R//P+39v\nAfBcnWN+vc8jWNTUX6jZILxHpA1IYmVgPeBVNR9rH6/N0mB+BniqzvEsy4dY/2MBWTDXhnPf48UR\nywXzSM6pL8jH0i/QyX5RjK9zrDDA1yew/C+ggX4xTSRr+T+X/109A8yr+TivwddefhzBwlb9fVg6\nw81Oh3aXk3gF8FrgdflR+3g88Gh+/DM/ah/PBuaQBcnithdfIRIiC/+JZL/kVgVW6fdxoMf9v7aI\npUE+l/q/LOsdT7u1Xx4ObRtU3sLcBNgS2LzmmAg8BPyp38eHgCda2cq1kcvDfwJLA/wV+VGva6r/\n8Qqyln6jcJ8DPFFzPON/B63n0LZlSKwAbAtMzT9uQ9YyuxO4p+Z4xD+Q3SH/xb0ygwf7K/NjzZpj\nBeBJlg3ywY6nfcO3MYe2IbERsDewK1lYPwjcBPwGuC2CWQnLs4qSGA+swbJB3nesVedrK5G12PuH\n+ePALLJutZc/RrCgjadTGg7tLiWxAXAAsB+wPnAZcA1wQwRPpazNupPEWOqH/FpkN6/Xqfm4Dtlo\nnGWCnDrhDsyO4KV2nkuRHNpdJB9itxdwGLA1cD5wAXCLbzRZleR99KuyfJDXC/c1yUYi1Qv0WcBj\nLL1J/lTZu/0KC21Jrwd+VvOljYEvR8SJI3ljGzqJMWSt6i8CTwOnABdE8HzSwszaIO+TX536gb4O\nsC5Lh6VOYNkQrz1qvz4vVbi3paUtaRTZkK+tI+KRkbyxDY3ETsDJZC2LY4Eby96SMEtFYgLLhvhA\nxxjqB/syAR/Bs62vcXjZOdQZkdOAh/sC24onsRJwErAjMCOCSxOXZFZ6+c3NP+fHgPKfr3rh/rb8\n47rAehJLyEL8H2QN13/UefxEO0bNDDW09wd+WkQhtjyJ1wEXA7cDm0UwP3FJZh0l/5nqm5dQV97v\n3jc7uO+YBLwZ2KPm81UlHmNpiNcL+MdGOqO16e4RSePyN900Ip6o+bq7Rwog8XrgRuA/gVPdFWJW\nbvnQyL5lHiblR+3jSWQjaJ4E/gHaqujukT2A39UG9tJidUzNp70R0TvUQmwpibWB64AvRPCjxOWY\nWRMieIFBumQk9cDonWDNibDmKsBWw3mfobS0fwZcHRFn9/u6W9otlP9X7GLgDxEclboeMytGoaNH\nJE0E/gZsFBHP9vueQ7uFJHYFTgQ2j+DF1PWYWTEKHT0SEc+RzXCy4h0BHO/ANrN6PCOyRPJFnp4G\n1vJIEbPONtzs9B6R5bIZ8LAD28wG4tAul9XIVkMzM6vLoV0uAYxOXYSZlZdDu1z+Qrbdl5lZXQ7t\ncvkbMFFi3dSFmFk5ObRLJJ+qfiWwb+pazKycHNrl81PgoHxmpJnZMhza5XMN2Ypiu6QuxMzKx6Fd\nMhEsJlvZ76v5Th1mZi9zKJTT+cBisj0gzcxe5mnsJSWxGXATsGUEf09dj5m1lqexd5gI7geOB34m\nMS51PWZWDm5pl1jep30J8NcIZqSux8xaxy3tDpRvEvpBYA/J/dtmNvSNfa3NIpgrsTtwi8Qs78Zu\n1t0c2hUQwcMSewNXS8yN4KbUNZlZGu4eqYgI7gTeC1wg0ZO4HDNLxKFdIRHcALwH+LnETqnrMbP2\nc2hXTAS9wLvJhgLuk7gcM2sz92lXUAQ35Tcnr5BYO4Ifpq7JzNrDoV1REdwlMRW4VmI94Oh8iKCZ\ndTBPrqk4ibWAi4HHgIMieC5xSWbWBE+u6VIRPA7sBMwHbpVYP3FJZlYgh3YHiOBF4BDgXOAOiWmJ\nSzKzgrh7pMNI7AycA5wKfC1fn9vMSma42enQ7kD5xsDnAQuB9+ddKO16bwGvBl4PbJA/XgNYFViR\nbJ3wF8n64P8M3Abc418u1m0c2rYMiTHAscBBwAER3FzAe4wCNgO2A95Sc8wHHiTbXf7vwOPAXGAB\nWZfcBGBdYBNgMtn2aicD38m7esw6nkPb6pKYDpwF/AD4egSLRvBaY4GtgKn5sR0wB/g1MBO4F7gv\ngieH+Lqbk/2C2RjYNYJZw63RrCoKC21JqwGnk7WoAjg0In470je29pGYBJxJ1kVxYAT/N4Q/uwGw\nG7A72SiVvwA3A7cAt7YqYPNula8A04FtPebcOl2RoX02cFNEnClpDDAxIuaN9I2tvfKujMOBo4Ev\nAz+MYLmLLzEamAK8C9iDrD/6WrJd4n9ZZP94Hty3Ad+K4MKi3sesDAoJbUmrAjMjYuNWv7GlIfEG\nstElTwIfiuCfEisA04B9gL2BR8l2zLkSuKudrV6JjwFvj+DQdr2nWQpFTa7ZCHhC0lmS7pJ0mqQV\nh1eilUEED5L1Rd8BzJT4BTAb+DzwAPCOCLaI4NgI7kzQTfEH4DVtfk+zymi09sgYYEvg4xHxv5JO\nIPvh/krtkyQdU/Npb0T0trJIa60IFgJHS1xONtrj8AhmJy6rz2JgdOoizFpNUg+MfC38Rt0j6wC3\nRcRG+edTgM9HxJ41z3H3iLWMxIHA9Ajel7oWsyIV0j0SEbOARyRtkn9pGnD/MOoza9bbgPtSF2FW\nVs0szXoEcK6kccDDZGtcmBVlF/xvzGxAnlxjpSHxFrIRKxt6Wrt1Oi/Nap3gEOBsB7bZwNzStlKQ\nWI2s+23LCP6Wuh6zormlbVX3MeAKB7bZ4NzStuQk1iCbVDM1n/xj1vG8yp9VlsRJQERwROpazNpl\nuNnp3dgtKYlNgfcCb0hdi1kVuE/bkslX9TuBbJ3vOanrMasCh7aldAjZ0q8npS7ErCrcp21J5Bsz\nzASmRXBP6nrM2s1D/qwy8m6RU4GTHNhmQ+MbkZbCwcAksk0XzGwIHNrWVhJvBI4DdozgpdT1mFWN\nu0esbSQmAOcDX4jg96nrMasi34i0tpE4BXgF8L56mwqbdRNPrrFSk3g32VrZWzqwzYbPoW2Fy2c9\nngzsEcEzqesxqzL3aVuh8iVXLwGOjODO1PWYVZ37tK0wEqOBy4CHI5iRuh6zMvHkGiujY4GJwGdS\nF2LWKdynbYWQ2A84ENgqgoWp6zHrFA5tazmJrYFTgN0ieDx1PWadxN0j1lISG5DdePxQBHelrses\n0zi0rWUkVgWuBI6L4LLU9Zh1Io8esZaQGAtcATwEHOEJNGaD8+gRSyZfavX7wGLgkw5ss+L4RqS1\nwheBdwDbR7AodTFmncyhbSMi8W9k24ZNjuDZ1PWYdTqHtg2bxN7AV8la2LNS12PWDZoKbUl/BZ4h\n67NcGBFbF1mUlZ/EZOB0YHoED6Wux6xbNNvSDqAnIp4qshirBonNgIuAD3gRKLP2GsroEQ/rs77J\nM1cDn47gl6nrMes2zYZ2ANdLulPSh4ssyMpLYl3geuD4CM5NXY9ZN2q2e2RyRDwmaU3gOkkPRsQt\nfd+UdEzNc3sjoreFNVoJSKwBXAf8KIITU9djVjWSeoCeEb/OUGdESjoamB8R384/94zIDiexCnAD\nWSv7KE+eMRu5wmZESlpR0sr544nArsB9Qy/RqkhiRbLp6bfjwDZLrpnukbWBiyX1Pf/ciPANqC4g\nsQJwMfAXvJ6IWSl4wSirS2IM8HNgCbC/p6ebtdZws9MzIm05EqOAs4AJwLsc2Gbl4dC2ZeSBfTLw\namCPCF5KXJKZ1XBo28vyJVZPAt4C7B7B84lLMrN+HNoGLLMm9hZkezs+k7gkM6vDoW19gf09YCtg\nVwe2WXk5tLtcHtjfBbYhC+x5iUsys0E4tLtYHtjfASYDu0QwN3FJZtaAQ7tL5YF9PDAVB7ZZZTi0\nu1Ae2N8iW7xmWgRPp63IzJrl0O4yeWB/E9gZ2NmBbVYtDu0uUhPYu5IFtnciMqsYh3aXyAP7BLKb\njjtHMCdxSWY2DA7tLpBPTT+FbKbjNN90NKsuh3aHkxgNnAFsTDYO+9nEJZnZCDi0O5jEWODHwJpk\niz89l7gkMxshh3aHkhgHnEe2vOpeESxIXJKZtUCzu7FbhUiMBy4CRgP7OLDNOodDu8PkezpeCjwP\nvDuCFxOXZGYt5NDuIBIrAVcCjwMHRLAwcUlm1mIO7Q4hsSpwLfAwcLC3CDPrTA7tDiCxJnADMBP4\nSASLE5dkZgVxaFecxHrAzcA1wBERLElckpkVyKFdYRKvAW4BzorgixFE6prMrFgO7YqSeBNwE/DN\nCI5LXY+ZtYcn11SQxNbAZcCnIjgvdT1m1j4O7YqR2BE4H/hQBJenrsfM2suhXSESewFnAu+J4MbU\n9ZhZ+7lPuyIk3gecBrzTgW3WvZoKbUmjJc2U5P+OJyBxGNmejtMiuCN1PWaWTrPdI58AHgBWLrAW\nq0Pic8BHgR0ieDh1PWaWVsOWtqRJwHTgdECFV2RAtj2YxDeAQ4CpDmwzg+Za2t8FPgusUnAtlpMY\nA5wKvAmY4v0czazPoKEtaU/g8YiYKalnkOcdU/Npb0T0tqS6LiQxgaWbF+wcwfzEJZlZC+QZ2jPi\n14kYeOazpK8DBwKLgPFkre0LI+KDNc+JiHC3SQvkK/VdBvwTOCiClxKXZGYFGW52Dhra/d5gB+DI\niNirFW9sy5JYh2zRp1uAT3jhJ7PONtzsHOo4bS9IVIB84adbgQuBGQ5sMxtI0y3tAV/ALe0Rkdgc\nuAr4WgSnpK7HzNpjuNnpaewJSWwP/AI4PIILUtdjZuXn0E5EYm+yse8HRHB96nrMrBq89kgCEoeQ\njcOe7sA2s6FwS7vNJD4LHA70RPDH1PWYWbU4tNtEYhRwPLArMDmCRxOXZGYV5NBuA4kVgLOBV5Gt\nI/J04pLMrKLcp12wfJbjNWS/IHd1YJvZSDi0CySxHtkMx98D743ghcQlmVnFObQLIrEp8BvgJ2Sz\nHBcnLsnMOoD7tAsgMYVsSvqREZyTuh4z6xwO7RaT2IdsDPYHIvhl6nrMrLM4tFtI4mPAF4HdI7gr\ndT1m1nkc2i0gIeC/gP3IhvT9OXFJZtahHNojJDEWOA14A7BdBE8mLsnMOphDewQkViJbpW8h2dZg\nzyUuycw6nIf8DZPE2kAv8AiwjwPbzNrBoT0MEq8jG4N9OfCRCBYlLsnMuoS7R4ZIYmvgUuArEZyW\nuh4z6y4O7SGQmE628NOhEVyeuh4z6z7uHmmSxGHAGcBeDmwzS8Ut7QbydbC/DuxLNgb7T4lLMrMu\n5tAehMR44Czg1XgMtpmVgLtHBiDxSuA6YDQwzYFtZmXg0K5DYmOyIX23AftHsCBxSWZmgEN7OfmQ\nvluB70XwuQiWpK7JzKyP+7RrSPwL2ToiHtJnZqXk0M5JzAD+A9gjgjtT12NmVk/Xh7bEaOB4YDdg\ncgR/TVuRmdnAGoa2pPHATcAKwDjg0og4qujC2kFiRbI9HFcnC2zvlG5mpdbwRmREvADsGBFvBd4C\n7ChpSuGVFUxiLeAGYAGwmwPbzKqgqdEjEfF8/nAc2bjlpwqrqA0kNiEb0nc92V6OLyYuycysKU2F\ntqRRku4GZgM3RsQDxZZVHInJwM3ANyL4UgSRuiYzs2Y129JeknePTAK2l9RTaFUFkXgPcAlwUASn\np67HzGyohjR6JCLmSboSeDvZri0ASDqm5mm9EdFLieQb7x4JzAB2ieDuxCWZWZfJG7s9I36diMF7\nByStASyKiLmSJgDXAsdGxK/y70dEaKSFFEViDHAiMAV4ZwSPJC7JzGzY2dlMS3td4GxJo8i6U87p\nC+yyk1gFOJ+s7qkRzEtckpnZiDRsaTd8gZK2tCU2AK4Afg183Ps4mlmZDDc7O3LBKImtyIb0nQV8\n1IFtZp2i46axS+wLnAp8OIJLUtdjZtZKHRPaNSNEPgHsHsHvEpdkZtZyHRHaEmOBHwDvALb1CBEz\n61SVD22J1YALgJeAKRE8m7gkM7PCVPpGpMRGZDccHwTe5cA2s05X2dCW2JYssE+J4AiPEDGzblDJ\n7pF8DZEfAAdHcGXqeszM2qVSoZ2PEDkK+He8hoiZdaHKhLbEOLLx15uTjRB5NHFJZmZtV4nQllgd\nuBB4Btg+gvmJSzIzS6L0NyIlXkt2w/EuYF8Htpl1s1KHtsQU4FbgexF8JoLFqWsyM0uptN0jEu8H\nTgAOjOCa1PWYmZVB6UI7HyFyNHAwsFME96WtyMysPEoV2hITyJZT3RDYJoJZaSsyMyuX0vRpS6xL\ntu9kADs6sM3MlleK0JZ4K3A7cBVwQAQLEpdkZlZKybtHJPYGziDbEuz81PWYmZVZstDObzh+lmzT\ngndGcEeqWszMqiJJaOdT0n8IbEF2w9GbFpiZNaHtoS2xBnARMAeY6hmOZmbNa+uNSIlNyW44/gb4\nVwe2mdnQtK2lLbEbcA7wuQh+1K73NTPrJG0JbYmPA18ia13f0o73NDPrRIWGtsQY4HvAjsB2Efy5\nyPczM+t0hYV2vkv6z4ElZJsWzCvqvczMukUhNyLzNbBvI9slfU8HtplZazQMbUnrS7pR0v2Sfi9p\nxuDPZweyNbBPjGCGd0k3M2udZlraC4FPRcRmwDbA4ZLeWO+JEocCF5CtgX1K68pMR1JP6hqK5POr\ntk4+v04+t5FoGNoRMSsi7s4fzwf+ALyq9jkSoyW+RbZT+vYRXFdEsYn0pC6gYD2pCyhYT+oCCtaT\nuoAC9aQuoIyGdCNS0oZkU89v7/eti4BVyKakz2lJZWZmtpymb0RKWgn4BfCJvMVd6wlgNwe2mVmx\nFBGNnySNBa4Aro6IE/p9r/ELmJnZciJCQ/0zDUNbkoCzgTkR8alh1mZmZi3QTGhPAW4G7iXbCgzg\nqIjwDulmZm3WVPeImZmVQ1M3IiWdKWm2pPsGec6Jkh6SdI+kLVpXYvEanZ+kHknzJM3Mjy+1u8aR\naHaCVFWvYTPnV9VrKGm8pNsl3S3pAUn/PcDzqnrtGp5fVa9dLUmj89ovH+D7zV+/iGh4AFPJhvrd\nN8D3pwNX5Y/fAfy2mdcty9HE+fUAl6WucwTntw7w1vzxSsAfgTd2yjVs8vwqew2BFfOPY4DfAlM6\n5do1eX6VvXY15/Bp4Nx65zHU69dUSzsibgGeHuQpe5PdrCQibgdWk7R2M69dBk2cH8CQ7/KWRTQx\nQYoKX8Mmzw8qeg0j4vn84ThgNPBUv6dU9tpBU+cHFb12AJImkQXz6dQ/jyFdv1YtGLUeLLPP4z+A\nSS167TIIYLv8vy5XSdo0dUHDNcgEqY64hoOcX2WvoaRRku4GZgM3RsQD/Z5S6WvXxPlV9trlvku2\nifmSAb4/pOvXylX++v8G6aQ7nHcB60fE5sD3gUsS1zMsDSZIQcWvYYPzq+w1jIglEfFWsh/k7QdY\nk6Oy166J86vstZO0J/B4RMxk8P8tNH39WhXajwLr13w+Kf9aR4iIZ/v+CxcRVwNjJa2euKwhySdI\nXQj8JCLq/aOv9DVsdH6dcA0jYh5wJfD2ft+q9LXrM9D5VfzabQfsLekvwHnATpJ+3O85Q7p+rQrt\ny4APAkjaBpgbEbNb9NrJSVo7n2SEpK3JhkrW63crpbz2M4AHot+M1hqVvYbNnF9Vr6GkNSStlj+e\nAOwCzOz3tCpfu4bnV9VrBxARX4iI9SNiI2B/4IaI+GC/pw3p+jW1YJSk84AdgDUkPQIcDYzNizo1\nIq6SNF3Sn4DngEOGeG5JNTo/YD/go5IWAc+T/eVXyWTgA8C9kvp+IL4AvBo64ho2PD+qew3XBc6W\nNIqskXVORPxK0mHQEdeu4flR3WtXTwCM5Pp5co2ZWYUUst2YmZkVw6FtZlYhDm0zswpxaJuZVYhD\n28ysQhzaZmYV4tA2M6sQh7aZWYX8P4ejIjrEn8H3AAAAAElFTkSuQmCC\n", "text/plain": "<matplotlib.figure.Figure at 0x107f93c50>"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": null, "cell_type": "code", "source": "", "outputs": [], "metadata": {"collapsed": true, "trusted": true}}, {"execution_count": 61, "cell_type": "code", "source": "from IPython.html import widgets\nfrom IPython.display import display\n\ndef bezier_with_steps(steps=1):\n plot_curve(bezier_curve(points, steps))\n\nw=widgets.interactive(bezier_with_steps,steps=widgets.IntSliderWidget(min=1, max=100, step=1, value=1))\ndisplay(w)", "outputs": [{"output_type": "display_data", "data": {"image/png": "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\nv7oAAAAASUVORK5CYII=\n", "text/plain": "<matplotlib.figure.Figure at 0x1097095d0>"}, "metadata": {}}], "metadata": {"collapsed": false, "trusted": true}}, {"execution_count": null, "cell_type": "code", "source": "", "outputs": [], "metadata": {"collapsed": true, "trusted": true}}], "nbformat": 4, "metadata": {"kernelspec": {"display_name": "Python 2", "name": "python2", "language": "python"}, "language_info": {"mimetype": "text/x-python", "nbconvert_exporter": "python", "version": "2.7.9", "name": "python", "file_extension": ".py", "pygments_lexer": "ipython2", "codemirror_mode": {"version": 2, "name": "ipython"}}}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment