Last active
November 30, 2019 18:55
-
-
Save blzzua/7640cd420960c01e0b252ef5584cd621 to your computer and use it in GitHub Desktop.
bspline with out numpy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import numpy as np | |
# cv = list of 2d control vertices | |
# n = number of samples (default: 100) | |
# d = curve degree (default: cubic = 3) | |
# closed = is the curve closed (periodic) or open? (default: open) | |
def bspline(cv, n=100, d=3, closed=False): | |
# Create a range of u values | |
count = len(cv) | |
knots = None | |
u = None | |
if not closed: | |
u = [ (float(i/(n-1)) * (count-d)) for i in range(0,n) ] # keep u=0 relative to 1st cv | |
knots = [0]*d + [ a for a in range(count-d+1)] + [count-d]*d | |
else: | |
u = [ ((float(i)/(n-1) * count) - (0.5 * (d-1))) % count for i in range(0,n) ] # keep u=0 relative to 1st cv | |
knots = [i for i in range(0-d,count+d+d-1) ] | |
# Simple Cox - DeBoor recursion | |
def coxDeBoor(u, k, d): | |
# Test for end conditions | |
if (d == 0): | |
if (knots[k] <= u and u < knots[k+1]): | |
return 1 | |
return 0 | |
Den1 = knots[k+d] - knots[k] | |
Den2 = knots[k+d+1] - knots[k+1] | |
Eq1 = 0; | |
Eq2 = 0; | |
if Den1 > 0: | |
Eq1 = ((u-knots[k]) / Den1) * coxDeBoor(u,k,(d-1)) | |
if Den2 > 0: | |
Eq2 = ((knots[k+d+1]-u) / Den2) * coxDeBoor(u,(k+1),(d-1)) | |
return Eq1 + Eq2 | |
# Sample the curve at each u value | |
samples = [ [0,0] for i in range(n) ] | |
for i in range(n): | |
if not closed: | |
if u[i] == count-d: | |
samples[i] = cv[-1] | |
else: | |
for k in range(count): | |
coxDeBoor_factor = coxDeBoor(u[i],k,d) | |
samples[i] = [ component[0] + coxDeBoor_factor * component[1] | |
for component in zip(samples[i],cv[k]) ] | |
else: | |
for k in range(count+d): | |
coxDeBoor_factor = coxDeBoor(u[i],k,d) | |
samples[i] = [ component[0] + coxDeBoor_factor * component[1] | |
for component in zip(samples[i],cv[k%count]) ] | |
return samples | |
if __name__ == "__main__": | |
from graph import * | |
cv = [[ 230, 195], | |
[ 380, 230], | |
[ 750, 187], | |
[ 630, 520], | |
[ 427, 790], | |
[ 260, 507], | |
[ 183, 308], | |
[ 145, 200]] | |
canvasSize(900,900) | |
windowSize(900,900) | |
for mult in [1,2,10]: | |
splined_cv = bspline(cv, n=len(cv) * mult , d=2, closed=True) | |
splined_cv = [ [v[0],v[1]] for v in splined_cv ] | |
orig_cv = [ [v[0],v[1]] for v in cv ] | |
brushColor("#dee9af"); penColor("black"); penSize(1) | |
polyline(splined_cv) | |
penColor("red"); penSize(2) | |
orig_cv.append(orig_cv[0]) | |
polyline(orig_cv) | |
run() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment