@gferreira Thanks!
MauriceMeilleur
@MauriceMeilleur
Posts made by MauriceMeilleur

RE: Import python file.
@gferreira Gustavo, is this a good way to build libraries of classes and functions, too? I'm thinking smallerscale, for a set of my own sketches, not something totally builtout and documented.

RE: Text to outlines > find objects with similar fill > Boolean operations?
@frederik But I figured it out! Obviously the fill/stroke properties from the formatted strings won't find their way into the Bezier paths, but I can just add them to the paths directly. (I guess I could just use text, but I want some flexibility in the code for when Kast is a variable font.) Just have to write the code to clean/chop up strings into even lines and size the text to position/size the lines to make fields.
A really useful Mauricebot would tell me to do the work first and then post just to share the results and the code.

RE: Text to outlines > find objects with similar fill > Boolean operations?
Seriously, I should ask for my own category on this forum, where I can post questions as a way of prompting myself to figure out the answers on my own. The solution is to draw the outlines of all the text in each color/layer into a single path, then remove overlaps, fill and stroke as needed to create/reinforce the illusion of continuous solid surfaces. It should be relatively easy to set up basic string operations to slice up sample text and to get the dimensions of the text boxes on the fly to adjust positioning and offset on the canvas before drawing. Unlike the above image, this one is all DrawBot:
This is an old version of Kast, by the way—new versions in different dimensions and side textures coming soon, among other places to a TDC type design competition entry near you …

RE: Text to outlines > find objects with similar fill > Boolean operations?
Okay, figured out the answer to the first question, just didn't know how to phrase the search: draw text into a BezierPath. Alignment will be a fun problem to tackle. Still searching for an answer to the second question, about finding shapes with similar properties and performing pathfinder operations on them.

Text to outlines > find objects with similar fill > Boolean operations?
This is sort of a followon to @ThunderNixon Stephen's thread from August: https://forum.drawbot.com/topic/184/efficientwaytoconvertalltexttooutlinesinamultipagedoc
Is there any easy, or even notstupidlyhard way, to:

convert type to outlines, preferably retaining its fill color?

find all shapes with a specified fill color and perform Boolean pathfinderlike operations on them?
I'm asking because once I have revisions to my font Kast complete, I'd like to be able to use it to generate specimen fields with effects like this:
and it would be nice (a) to generate them with scripts and (b) without having to use Illustrator. (I think I speak for most DB users when I say: the less I can get away with having to use Illustrator, or really any Adobe product once PageBot is a bit further along, the better.)


RE: A little arcTo() and geometry help?
The finished product, a tribute to Bridget Riley's Rustle 6 (2015).
import math canvasX = 600 canvasY = 600 nFrames = 120 side = canvasX/14 height = (side * sqrt(3))/2 center = (side/sqrt(3))/2 nX = 14 nY = 15 offsetX = side offsetY = height from datetime import * time = datetime.now() def interpolate(pt1, pt2, ratio): assert ratio <= 1 return (pt1[0] + (ratio * (pt2[0]  pt1[0])), pt1[1] + (ratio * (pt2[1]  pt1[1]))) def triangle(s, h, c, inout): assert inout >= 0 and inout <= 1 start = (s/2, h/2) pivot = (0, h/2  (c * 3)) target = (s/2, h/2) control = interpolate((s/2, c/2), (0, h/2  c), inout) radius = s # optimal distance to control points is (4/3)*tan(pi/(2n); thank you https://stackoverflow.com/users/16673/suma for answering this question https://stackoverflow.com/questions/1734745/howtocreatecirclewithb%C3%A9ziercurves control_ratio = ((4/3 * tan(pi/12)) * radius) / (2 * c) controlP = interpolate(pivot, control, control_ratio) controlT = interpolate(target, control, control_ratio) triangle = BezierPath() triangle.moveTo(start) triangle.lineTo(pivot) triangle.curveTo(controlP, controlT, target) triangle.closePath() drawPath(triangle) def frame(x, y, m): f = BezierPath() g = BezierPath() f.rect(0, 0, x, y) g.rect(m, m, x  (2 * m), y  (2 * m)) f = f.difference(g) f.closePath() drawPath(f) # original Riley plan for Rustle 6 plan = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0], [1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0], [0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0], [0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1], [1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ] for n in range(nFrames): newPage(canvasX, canvasY) frameDuration(1/30) ex = sin(radians(n * (360/nFrames))) fill(1) rect(0, 0, canvasX, canvasY) with savedState(): translate(canvasX/2, canvasY/2) fill(0) translate((nX  1) * offsetX/2, (nY  1) * offsetY/2) for i in range(nY): with savedState(): translate(0, i * offsetY) if i % 2 == 0: for j in range(nX  1): with savedState(): translate(offsetX/2 + (j * offsetX), 0) triangle(side, height, center, .5  (ex * (plan[i][j] * .5))) else: for j in range(nX): with savedState(): translate(j * offsetX, 0) triangle(side, height, center, .5  (ex * (plan[i][j] * .5))) fill(1) frame(canvasX, canvasY, side/2) saveImage('~/Desktop/riley_tribute_test_01_%s.gif' %time)
The reference image:

RE: A little arcTo() and geometry help?
I solved a outlining problem from scratch, specifically with rounding corners of an outline with a variable radius, that I talked about on this earlier post here on the forum: https://forum.drawbot.com/topic/181/usingarctoforvariableradiuscornerrounding
I wound up using arcTo() to do that (if I get around to it, I'll post the code) and it didn't occur to me that one reason the solution worked was because I wasn't trying to draw anything but a circlebased curve that stayed convex in the same orientation.

RE: A little arcTo() and geometry help?
And I was right. Looking at the diagram I made suggested to me that the answer probably had something to do with tangents of the relevant angles. Searching for how to define circles with Bezier curves and throwing 'tangent' into search led me to this Stackoverflow thread, in which I learned:
1 that it is impossible to exactly represent a circle with Bezier curves, and
2 that the optimal distance of offcurve from oncurve points to define a circle with n segments is r * ((4/3) * tan(pi/(2n))). In my example, the ratio of this distance to the total distance of the oncurve to the defined extreme (for n = 6, the number of 60° arcs in a circle) is 0.6188021535170061, not very far from my guess of .625. The outside extreme/convex state:
and the inside extreme/concave state:
Extrapolating between the curves just means extrapolating from 0 to 1 in line 28 of the code below. As soon as the Riley tribute I can now make is done, I'll post it.
Thanks for watching this episode of Maurice Solving Problems Aloud.
import math canvas = 500 nFrames = 60 h = canvas/2 side = (2 * h)/sqrt(3) c = (side/sqrt(3))/2 from datetime import * time = datetime.now() def drawPt(pos, r=5): x, y = pos oval(xr, yr, r*2, r*2) newPage(canvas, canvas) fill(1) rect(0, 0, canvas, canvas) translate(canvas/2, canvas/2) fill(None) def interpolate(pt1, pt2, ratio): assert ratio <= 1 return (pt1[0] + (ratio * (pt2[0]  pt1[0])), pt1[1] + (ratio * (pt2[1]  pt1[1]))) start = (side/2, h/2) pivot = (0, h/2  (c * 3)) target = (side/2, h/2) control = interpolate((side/2, c/2), (0, h/2  c), 1) #0 is outside extreme, 1 inside radius = side # optimal distance to control points is (4/3)*tan(pi/(2n); thank you https://stackoverflow.com/users/16673/suma for answering this question https://stackoverflow.com/questions/1734745/howtocreatecirclewithb%C3%A9ziercurves control_ratio = ((4/3 * tan(pi/12)) * radius) / (2 * c) controlP = interpolate(pivot, control, control_ratio) controlT = interpolate(target, control, control_ratio) triangle = BezierPath() triangle.moveTo(start) triangle.lineTo(pivot) triangle.curveTo(controlP, controlT, target) triangle.closePath() stroke(0, 1, 1) drawPath(triangle) fill(None) stroke(1, 0, 0) polygon(start, pivot, target) stroke(0, 1, 1) polygon(pivot, control, target) for pt in [pivot, control, target]: drawPt(pt) stroke(1, 0, 1) for pt in triangle.onCurvePoints: drawPt(pt, r=3) for pt in triangle.offCurvePoints: drawPt(pt, r=2) stroke(None) fill(0, .15) drawPath(triangle) fill(None) stroke(1, 0, 0) oval(start[0]  side, start[1]  side, side * 2, side * 2) saveImage('~/Desktop/riley_tribute_test_01_%s.jpg' %time)

RE: A little arcTo() and geometry help?
Okay, I thought I'd figured it out—use curveTo() instead of arcTo()—but now my trig and knowledge of curves is failing me.
Using arcTo(), with the control point at the outside position, I get the curve I want: a curve defined by the arc of a circle (shown here in red), radius equal to the sides of the triangle, centered on the point opposite the curve and passing through the end points of the curve. With the control point at the other defined extreme, I get the curve concave to the triangle instead of convex.
But, as I said in the OP, I can't extrapolate points for arcTo() that would move the curve back and forth between those two positions.
Using curveTo(), on the other hand, does allow that kind of extrapolation. But here's the problem: if I put the offcurve points at the defined extreme, I don't get the curve I want.
Clearly they need to fall further back towards their respective oncurve points. But where, to get the curve matching the circle? Using trial and error I can approximate the curve with offcurve points .625 of the distance between the defined control point and the oncurve points:
But it's almost certainly not exact, and why should I have any reason to think there's anything trigonometrically significant about the ratio 5/8 here anyway? It seems like there should be a trigonometricallydefined solution for the offcurve points here that I'm missing …