Tyler Hobbs note to align and trim the plot after you finish it makes a lot of sense. I think I will add alignment dots to aid with the cutting on my plots.
Student Area
bookooBread – just different line weights for now
dinkolas-LineExercises
Foundations code https://editor.p5js.org/dinkolas/sketches/ayqItsA8l
Spiral line code https://editor.p5js.org/dinkolas/sketches/BX7T27HnO
Offset code https://editor.p5js.org/dinkolas/sketches/LEhTS9ozO
lemonbear-LineExercises
frog-LineExercises
aahdee – LineExercises
Dashed line
Living Line
[videopack id=”773″]https://courses.ideate.cmu.edu/60-428/f2021/wp-content/uploads/2021/09/livingline.mp4[/videopack]
Spicy Line
[videopack id=”778″]https://courses.ideate.cmu.edu/60-428/f2021/wp-content/uploads/2021/09/spicyline.mp4[/videopack]
Circle
Spiral
Parallel
[videopack id=”783″]https://courses.ideate.cmu.edu/60-428/f2021/wp-content/uploads/2021/09/DwM_LineExercises-2021-09-14-23-49-37.mp4[/videopack]
Different Weights
Calligraphic
[not an svg – im having some save errors. will add later]
sapeck-LineExercises
A: Dashed Line
/* * sapeck_03_A_DashedLine.pde * A dashed line between the center and the mouse * Originally created by sapeck 2021-09-14 * CMU 60-428 F21 Drawing With Machines */ int DASH_INTERVAL = 20; void setup() { size(640, 480); } void draw() { background(255, 255, 255); float d = dist(width/2, height/2, mouseX, mouseY); float num = d/DASH_INTERVAL; for (int i = 0; i <= num; i += 2) { float x1 = lerp(width/2, mouseX, i/num); float y1 = lerp(height/2, mouseY, i/num); float x2 = lerp(width/2, mouseX, min(1.0, (i+1)/num)); float y2 = lerp(height/2, mouseY, min(1.0, (i+1)/num)); line(x1, y1, x2, y2); } } void mouseClicked() { saveFrame("sapeck_03_A_DashedLine_####.png"); }
B: Living Line
/* * sapeck_03_B_LivingLine.pde * A mouse trail * Originally created by sapeck 2021-09-14 * CMU 60-428 F21 Drawing With Machines */ int NUM_POSITIONS = 100; // Two 2D arrays ArrayList x_positions = new ArrayList(); ArrayList y_positions = new ArrayList(); // One 2D Array ArrayList<Integer[]> xy_positions = new ArrayList<Integer[]>(); // One Array of Objects (PVectors) ArrayList pv_positions = new ArrayList(); void setup() { size(640, 480); } void mouseMoved() { // If there are 100 points recorded, remove the first one // This is a FIFO list, so the items are appended to the end // and removed from the beginning. if (x_positions.size() >= 100) { x_positions.remove(0); y_positions.remove(0); xy_positions.remove(0); pv_positions.remove(0); } // Add the new location x_positions.add(mouseX); y_positions.add(mouseY); Integer[] xy = { mouseX, mouseY }; xy_positions.add(xy); PVector pv = new PVector(mouseX, mouseY); pv_positions.add(pv); } void draw() { background(255, 255, 255); beginShape(); for (int i = 0; i < pv_positions.size(); i++) { // Loop over each item in the list and add a point // to the line PVector pv = pv_positions.get(i); vertex(pv.x, pv.y); } endShape(); } void mouseClicked() { saveFrame("sapeck_03_B_LivingLine_####.png"); }
C: Spicy Line
/* * sapeck_03_C_SpicyLine.pde * A mouse trail that gets spicy * Originally created by sapeck 2021-09-14 * CMU 60-428 F21 Drawing With Machines */ int NUM_POSITIONS = 100; float RANDOMNESS_START = 1; float RANDOMNESS_RATE = 0.008; // One Array of Objects (PVectors) ArrayList pv_positions = new ArrayList(); float randomness = RANDOMNESS_START; void setup() { size(640, 480); } void mouseMoved() { // Increase the randomness over time of movements randomness += RANDOMNESS_RATE; // If there are 100 points recorded, remove the first one // This is a FIFO list, so the items are appended to the end // and removed from the beginning. if (pv_positions.size() >= 100) pv_positions.remove(0); // Add the new location float x = mouseX + random(-1 * randomness, randomness); float y = mouseY + random(-1 * randomness, randomness); PVector pv = new PVector(x, y); pv_positions.add(pv); } void draw() { background(255, 255, 255); beginShape(); for (int i = 0; i < pv_positions.size(); i++) { // Loop over each item in the list and add a point // to the curve PVector pv = pv_positions.get(i); vertex(pv.x, pv.y); } endShape(); } void mouseClicked() { saveFrame("sapeck_03_C_SpicyLine_####.png"); }
D: One Circle, Two Ways
Sine and Cosine Points
/* * sapeck_03_D_OneCircleTwoWays_SINCOSPoints.pde * A circle made from sine and cosine points * Originally created by sapeck 2021-09-14 * CMU 60-428 F21 Drawing With Machines */ int NUM_POINTS = 20; float CIRCLE_RADIUS = 100; // One Array of Objects (PVectors) PVector pv_positions[] = new PVector[NUM_POINTS]; void setup() { size(640, 480); for (int i = 0; i < NUM_POINTS; i++) { float x = CIRCLE_RADIUS * cos(i * (TWO_PI / NUM_POINTS)) + (width / 2); float y = CIRCLE_RADIUS * sin(i * (TWO_PI / NUM_POINTS)) + (height / 2); pv_positions[i] = new PVector(x, y); } } void draw() { background(255, 255, 255); beginShape(); for (int i = 0; i < NUM_POINTS; i++) { // Loop over each item in the list and add a point // to the curve PVector pv = pv_positions[i]; vertex(pv.x, pv.y); } endShape(CLOSE); } void mouseClicked() { saveFrame("sapeck_03_D_OneCircleTwoWays_SINCOSPoints_####.png"); }
Cosine and Square Root
/* * sapeck_03_D_OneCircleTwoWays_SQRT.pde * A circle made from cosine and square root * Originally created by sapeck 2021-09-14 * CMU 60-428 F21 Drawing With Machines */ int NUM_POINTS = 20; float CIRCLE_RADIUS = 100; // One Array of Objects (PVectors) PVector pv_positions[] = new PVector[NUM_POINTS]; float CIRCLE_RADIUS_SQ = pow(CIRCLE_RADIUS, 2); void setup() { size(640, 480); for (int i = 0; i < NUM_POINTS; i++) { float x = CIRCLE_RADIUS * cos(i * (TWO_PI / NUM_POINTS)); float x_sq = pow(x, 2); float y = sqrt(CIRCLE_RADIUS_SQ - x_sq); float x_aligned = x + (width / 2); float y_aligned = (height / 2) + y; if (i > NUM_POINTS / 2) y_aligned -= 2 * y; pv_positions[i] = new PVector(x_aligned, y_aligned); } } void draw() { background(255, 255, 255); beginShape(); for (int i = 0; i < NUM_POINTS; i++) { // Loop over each item in the list and add a point // to the curve PVector pv = pv_positions[i]; vertex(pv.x, pv.y); } endShape(CLOSE); } void mouseClicked() { saveFrame("sapeck_03_D_OneCircleTwoWays_SQRT_####.png"); }
E: Spiral
/* * sapeck_03_E_Spiral.pde * A spiral made from a circle with increasing radius * Originally created by sapeck 2021-09-14 * CMU 60-428 F21 Drawing With Machines */ int POINTS_PER_ROTATION = 10; int NUM_POINTS = 50; float RADIUS_GROWTH_PER_POINT = 4; // One Array of Objects (PVectors) PVector pv_positions[] = new PVector[NUM_POINTS]; float radius = 0; void setup() { size(640, 480); for (int i = 0; i < NUM_POINTS; i++) { float theta = i * (TWO_PI / POINTS_PER_ROTATION); float x = radius * cos(theta) + (width / 2); float y = radius * sin(theta) + (height / 2); pv_positions[i] = new PVector(x, y); radius += RADIUS_GROWTH_PER_POINT; } } void draw() { background(255, 255, 255); beginShape(); for (int i = 0; i < NUM_POINTS; i++) { // Loop over each item in the list and add a point // to the curve PVector pv = pv_positions[i]; curveVertex(pv.x, pv.y); } endShape(); } void mouseClicked() { saveFrame("sapeck_03_E_Spiral_####.png"); }
F: Parallel Polyline
For this one, I used vsketch, vpype, and shapely. It’s as simple as installing these Python packages and then running “vsk run” and it will bring a viewer, auto-reload your code, and save an SVG for you when you click the “LIKE!”button.
#!/usr/bin/env python3 # # sapeck_03_F_ParallelPolyline.py # Draw a teardrop-like shape with inner and outer offset lines # Originally created by sapeck 2021-09-15 # CMU 60-428 F21 Drawing With Machines # from math import cos, sin from shapely.geometry import LineString, MultiLineString import vsketch PI = 3.14159 class Sapeck03FParallelpolylineVskSketch(vsketch.SketchClass): CIRCLE_POINTS = 100 RADIUS = 2 def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("letter", landscape=False) vsk.scale("in") # This makes a teardrop-like shape points = [(0, 0)] for i in range(0, self.CIRCLE_POINTS): x = self.RADIUS * cos(i * (PI / self.CIRCLE_POINTS)) y = self.RADIUS * sin(i * (PI / self.CIRCLE_POINTS)) + self.RADIUS + 1 points.append((x, y)) points.append((0, 0)) # points is just an array of (x, y) points line = LineString(points) vsk.stroke(1) vsk.geometry(line) # Now make the inner and outer offsets vsk.stroke(2) offset0 = line.parallel_offset(1, 'left', join_style=2, mitre_limit=10.0) # inner offset offset1 = line.parallel_offset(1, 'right', join_style=2, mitre_limit=10.0) # outer offset vsk.geometry(offset0) vsk.geometry(offset1) def finalize(self, vsk: vsketch.Vsketch) -> None: # We can automatically apply vpype settings here too! vsk.vpype("linemerge linesimplify reloop linesort") if __name__ == "__main__": Sapeck03FParallelpolylineVskSketch.display()
G: Lines of Different Weights
#!/usr/bin/env python3 # # sapeck_03_G_LinesOfDifferentWeights.py # Draw different weight lines using offset curves # Originally created by sapeck 2021-09-15 # CMU 60-428 F21 Drawing With Machines # from math import cos, sin from shapely.geometry import LineString, MultiLineString import vsketch PI = 3.14159 class Sapeck03GLinesofdifferentweightsSketch(vsketch.SketchClass): CIRCLE_POINTS = 100 RADIUS = 2 OFFSET_AMOUNT = 0.0025 OFFSET_NUM = 10 def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("letter", landscape=False) vsk.scale("in") # This makes a teardrop-like shape points = [(0, 0)] for i in range(0, self.CIRCLE_POINTS): x = self.RADIUS * cos(i * (PI / self.CIRCLE_POINTS)) y = self.RADIUS * sin(i * (PI / self.CIRCLE_POINTS)) + self.RADIUS + 1 points.append((x, y)) points.append((0, 0)) # points is just an array of (x, y) points line = LineString(points) vsk.stroke(1) vsk.geometry(line) # Now make the inner offsets vsk.stroke(2) for i in range(0, self.OFFSET_NUM): offset = line.parallel_offset(i * self.OFFSET_AMOUNT, 'left', join_style=2, mitre_limit=10.0) # inner offset vsk.geometry(offset) def finalize(self, vsk: vsketch.Vsketch) -> None: vsk.vpype("linemerge linesimplify reloop linesort") if __name__ == "__main__": Sapeck03GLinesofdifferentweightsSketch.display()
H: Calligraphic Polyline
#!/usr/bin/env python3 # # sapeck_03_H_CalligraphicPolyline.py # Draw a calligraphic sine wave # Originally created by sapeck 2021-09-15 # CMU 60-428 F21 Drawing With Machines # from math import cos, dist, sin import numpy as np from shapely.geometry import LineString, MultiLineString, Point from shapely.ops import unary_union import vsketch PI = 3.14159 class Sapeck03HCalligraphicpolylineSketch(vsketch.SketchClass): CIRCLE_POINTS = 1000 RADIUS = 3 #OFFSET_AMOUNT = 0.0025 OFFSET_AMOUNT = 0.0025 OFFSET_MULTIPLIER = 600 BLEED_OVER = 1 def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("letter", landscape=True) vsk.scale("in") # This makes a teardrop-like shape points = [] for i in range(0, self.CIRCLE_POINTS): x = i * (2 * PI / self.CIRCLE_POINTS) y = self.RADIUS * sin(x) points.append((x, y)) last = None for point_i in range(0, len(points) - 1): prev_point = points[len(points) - 1] if point_i == 0 else points[point_i - 1] point = points[point_i] next_point = points[0] if point_i == len(points) - 1 else points[point_i + 1] change = dist(point, next_point) if change == 0: continue weight = 1 / (change * self.OFFSET_MULTIPLIER) # width of line num_lines = int(change / self.OFFSET_AMOUNT) orig = LineString([point, next_point]) for i in range(1, num_lines + self.BLEED_OVER): next_point_shortened = orig.interpolate(i / num_lines, normalized=True) orig_short = LineString([Point(point[0], point[1]), next_point_shortened]) # find perpendicular https://stackoverflow.com/a/57072678 left = orig_short.parallel_offset(weight / 2, 'left') right = orig_short.parallel_offset(weight / 2, 'right') c = left.boundary[1] d = right.boundary[0] # note the different orientation for right offset last = d vsk.geometry(LineString([c, d])) def finalize(self, vsk: vsketch.Vsketch) -> None: vsk.vpype("linemerge linesimplify reloop linesort") if __name__ == "__main__": Sapeck03HCalligraphicpolylineSketch.display()
miniverse Lostritto
I agree with the author that computers cannot draw. When drawing with a stylus, the holder of the stylus is presumed as the intelligent creator. Unless the computer has a say in what is on the page, then they are not drawing. I would only consider a drawing produced by an algorithm which learns without observation as the drawer. The author makes an interesting point on replication and how that affects perception. If a machine can draw, then where does the drawing lie on the spectrum of uniqueness? Do we classify it as something completely special to that computer or do we see it as something replicable because it was made by a computer? Even for an AI drawing machine, cloning the algorithm on a different computer should produce the same results. So how unique is the uniqueness?
spingbing-LostrittoReading
Something that struck me in the Lostritto reading was that there were several factors that differentiated and constrained the definition of a drawing and that there were many that I didn’t completely agree with. For one, I considered the undo button as the digital perfection of the eraser on traditional pieces, but here he refers to them as completely different functions. The “A computer cannot draw” section also states that a drawing must be intended by the creator’s mind to be a drawing in order for it to be a drawing. More generally, this list leads me to believe that there can be art pieces that exist on separate incremental levels; for example, if a piece cannot be edited, was drawn with the intent of it being a drawing, and final, would that be closer to the sphere of drawing than one that also could not be edited, but was drawn without the intent of being a drawing, and final? Or, is everything that does not satisfy all the requirements on the same plane?
frog-PlotterSkimming
These takeaways come from Tyler Hobbs and Licia He
- I didn’t really consider the potential challenges of making a large drawing – Hobbs points out that breaking down a drawing into smaller drawings like tiles can allow for the creation of something large.
- I’m really interested in the mechanics of paint plotting. It seems that Licia’s methodology is to just immerse herself in the work and be as prolific as possible. She makes a lot of experiments with her materials.