Hi there. I’m working on a GUI for a MIDI synth editor I’m writing. I want to draw 28 small images, representing synthesis algorithms (a bit like the DX7 ones). I only need a few basic shapes. I’ve read the Pen help, but to be honest, I can’t figure out how to draw simple shapes. I don’t know much maths and even less geometry.
Would somebody be kind enough to post an example of how to draw simple shapes with Pen? In my case, I need equilateral triangle, square, and circle.
I guess I could make 28 gifs or pngs in another app, and show them using the Image class, but I’d rather not have a dependency on 28 image files.
I’m new to this forum (but not SC), so I hope this is posted in the right place.
Thanks very much.
Jim
Hi Jim,
Interesting question, so after playing a bit with it I came up with this:
(
~drawRect = {
|x, y, w, h|
var rect = Rect(x, y, w, h);
Pen.addRect(
rect
);
Pen.perform(\stroke);
};
~drawCircle = {
|x, y, r|
Pen.fillColor = Color.white;
Pen.strokeColor = Color.black;
Pen.addArc(x@y + ((r@r)), r, 0, 2pi);
Pen.fillStroke;
};
~drawTriangle = {
|x, y, length| // Length is not beam-length, but length from center to corner (=point on circle)
var loc = x@y + (length@length);
var rotation = -0.5pi;
var a = cos(0+rotation)@sin(0+rotation) * length;
var b = cos(2pi/3+ rotation)@sin(2pi/3 + rotation) * length;
var c = cos(2pi/3 * 2 + rotation)@sin(2pi/3 * 2 + rotation) * length;
a = a + loc;
b = b+ loc;
c = c + loc;
loc.postln;
Pen.moveTo(a);
Pen.lineTo(b);
Pen.lineTo(c);
Pen.lineTo(a);
Pen.perform(\stroke);
};
w = Window.new.front;
w.view.background_(Color.white);
w.drawFunc = {
var w = 50; var h = 50;
8.do{
|x|
8.do{
|y|
switch(3.rand,
0, {~drawRect.value(x * w, y*h, w, h)},
1, {~drawCircle.value(x * w, y*h, w*0.5)},
2, {~drawTriangle.value(x * w - 1,y*h + 5,w*0.51)}
)
}
};
};
w.refresh;
)
The function for the triangle is a bit tricky, since it’s based on points on a circle. Therefore positioning the triangle to fit in a grid needs some additional maths on the x and y (which I haven’t implemented), I went with trial & error.
I think this is a simpler way of finding the points for the triangle, using a bounding rectangle instead of a circle:
~drawTriangle = { |x, y, length|
var height = (length * 3.sqrt) / 2;
var a = Point(x + (length / 2), y);
var b = Point(x + length, y + height);
var c = Point(x, y + height);
Pen.moveTo(a);
Pen.lineTo(b);
Pen.lineTo(c);
Pen.lineTo(a);
Pen.stroke;
};
Since it now takes a full side length instead of radius, the line in drawFunc below would then be ~drawTriangle.value(x * w, y * h + 5, w)
1 Like
Hi Jildert,
That is exactly what I needed! I’m not sure I would ever have figured that out. Many thanks for your time and effort. 
@Eric_Sluyter: thanks also for your alternative version of the ~drawTriangle function. Much appreciated. Your approach could be very useful.
I’m not sure which ~drawTriangle function I’ll use yet, but I can figure it all out now. Thanks again, @Jildert & @Eric_Sluyter.
Jim