How to draw a wiggle line with Python
-
Last year I wrote a Drawbot tutorial on Medium.
If you want to jump directly into the code, here's the source:############################## # Draw Wiggles using Drawbot # ############################## """ Script by Roberto Arista, you can find the related tutorial here: https://medium.com/@roberto_arista/how-to-draw-a-wiggle-between-two-points-with-python-and-drawbot-788006c18fb0 You can find drawbot here: http://www.drawbot.com/ Code distributed with no guarantee, use at your own risk """ ### Modules from math import radians, atan2, sqrt, sin, cos from collections import namedtuple ### Constants BLACK = (0, 0, 0) Point = namedtuple('Point', ['x', 'y']) ### Function & procedures def calcAngle(pt1, pt2): return atan2((pt2.y - pt1.y), (pt2.x - pt1.x)) def calcDistance(pt1, pt2): return sqrt((pt1.x - pt2.x)**2 + (pt1.y - pt2.y)**2) def calcWiggle(pt1, pt2, waveLength, waveHeight, curveSquaring=.57): assert 0 <= curveSquaring <= 1, 'curveSquaring should be a value between 0 and 1: {}'.format(curveSquaring) assert waveLength > 0, 'waveLength smaller or equal to zero: {}'.format(waveLength) diagonal = calcDistance(pt1, pt2) angleRad = calcAngle(pt1, pt2) howManyWaves = diagonal//int(waveLength) waveInterval = diagonal/float(howManyWaves) maxBcpLength = sqrt((waveInterval/4.)**2+(waveHeight/2.)**2) bcpLength = maxBcpLength*curveSquaring bcpInclination = calcAngle(Point(0,0), Point(waveInterval/4., waveHeight/2.)) wigglePoints = [pt1] prevFlexPt = pt1 polarity = 1 for waveIndex in range(0, int(howManyWaves*2)): bcpOutAngle = angleRad+bcpInclination*polarity bcpOut = Point(prevFlexPt.x+cos(bcpOutAngle)*bcpLength, prevFlexPt.y+sin(bcpOutAngle)*bcpLength) flexPt = Point(prevFlexPt.x+cos(angleRad)*waveInterval/2., prevFlexPt.y+sin(angleRad)*waveInterval/2.) bcpInAngle = angleRad+(radians(180)-bcpInclination)*polarity bcpIn = Point(flexPt.x+cos(bcpInAngle)*bcpLength, flexPt.y+sin(bcpInAngle)*bcpLength) wigglePoints.append((bcpOut, bcpIn, flexPt)) polarity *= -1 prevFlexPt = flexPt return wigglePoints def drawCurvesSequence(wigglePoints): myBez = BezierPath() myBez.moveTo(wigglePoints[0]) for eachBcpOut, eachBcpIn, eachAnchor in wigglePoints[1:]: myBez.curveTo(eachBcpOut, eachBcpIn, eachAnchor) myBez.endPath() drawPath(myBez) ### Variables pt1 = Point(50, 50) pt2 = Point(150, 60) ### Instructions size(400, 400) oval(pt1.x-1, pt1.y-1, 2, 2) oval(pt2.x-1, pt2.y-1, 2, 2) stroke(*BLACK) strokeWidth(.5) fill(None) wigglePoints = calcWiggle(pt1, pt2, 16, 36, .7) drawCurvesSequence(wigglePoints)