geometry.py

At 8d263df

8d263dfHistory

Preview

Code · 1.6 KiB
"""Organic five-petal flower outlines, as explicit closed cubic Bézier paths."""
import numpy as np

def flower(center,radius,rotation=0,lengths=(1,.96,1.04,.92,1.02),widths=(.24,.25,.23,.26,.24),angles=(0,-.045,.035,-.035,.045),valleys=(.36,.39,.35,.40,.37)):
    center=np.asarray(center,float)
    theta=np.arange(5)*2*np.pi/5+rotation-np.pi/2+np.asarray(angles)
    middle=(theta+np.r_[theta[-1]-2*np.pi,theta[:-1]])/2
    neck=np.stack([np.cos(middle),np.sin(middle)],1)*np.asarray(valleys)[:,None]*radius
    path=[tuple(center+neck[0])]
    for i in range(5):
        a=theta[i];u=np.array([np.cos(a),np.sin(a)]);v=np.array([-np.sin(a),np.cos(a)])
        length=lengths[i]*radius; width=widths[i]*radius
        left=u*length*.72-v*width; tip=u*length; right=u*length*.72+v*width
        start=neck[i];finish=neck[(i+1)%5]
        ta=np.array([-np.sin(middle[i]),np.cos(middle[i])])
        tb=np.array([-np.sin(middle[(i+1)%5]),np.cos(middle[(i+1)%5])])
        segments=[(start+ta*radius*.080,left-u*length*.23,left),
                  (left+u*length*.19,tip-v*width*.57,tip),
                  (tip+v*width*.57,right+u*length*.19,right),
                  (right-u*length*.23,finish-tb*radius*.080,finish)]
        for segment in segments:
            path.extend(tuple(center+p) for p in segment)
    return path

def curve_points(curve,count=60):
    points=[];p=np.asarray(curve[0],float);t=np.linspace(0,1,count,endpoint=False)[:,None]
    for i in range(1,len(curve),3):
        a,b,c=np.asarray(curve[i:i+3],float)
        points.extend((1-t)**3*p+3*(1-t)**2*t*a+3*(1-t)*t*t*b+t**3*c);p=c
    return np.asarray(points)

Files