Simple Pen examples?

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. :slight_smile:

@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