@kmll – it would be nice if we had a simple graph-mode library that inverted the y-axis, scaled the display and corrected the strokeWeight accordingly, drew a graph paper with labeled axis, and then got out of the way and let the student writing simple vanilla sketches on top of it without requiring that they use a library API. If I was going to write something like that I would probably use grafica to do it:
https://jagracar.com/sketches/multiplePanels.php
https://jagracar.com/sketches/multiplePlots.php
Putting a graphing-calculator-display-style for drawing sketches aside for a moment:
I think the thing confusing me here is that the lesson plan for teaching a math student to solve the intersection of two linear equations (pen & paper) looks very different from the way that I would teach a computer science student to program the rendering of intersecting line segments, or to solve programmatically for a line-line intersection. I’m trying to understand: is this an algebra class in solving equations or a programming class in how to render lines or find points with algorithms? or both? What level are the students, and what are the learning goals?
Here’s an “intersection of two lines” algebra lesson of the kind that I’m familiar with:
http://zonalandeducation.com/mmts/intersections/intersectionOfTwoLines1/intersectionOfTwoLines1.html
Algebra process:
- find
y = 2x + 1
and y = -x + 4
- set
y
s equal to each other: 2x + 1 = -x + 4
- reduce one side to
x
: 3x = 3
… x = 1
- plug x value into either equation to solve y:
y = 2+1
… y = 3
- give solution for intersection point:
(1, 3)
The process produces an answer point. If we want the students to get pictures of the lines then they can learn (on paper) to find two points on each line (one on either side of the intersection, if that is the point of interest) and then mark each line with a straight edge. We can also teach them how to use a graphing calculator app – like https://www.desmos.com/calculator. They type in the equations and get pictures. These exist for the web, laptops, iOS and Android etc.
But I’m assuming the goal isn’t to create a graphing calculator app for students in Processing and have them use it – it is to have them program their equations. However, algebraic equations aren’t typically how you write a program to draw a line or solve for an intersection. If your goal is to teach how to draw a line with a computer, the normal way is to define a line segment with two points – like in Processing:
line(x1, y1, x2, y2).
Intro to line programming process:
- determine the current display range, e.g. -200 to 200. This is a size of 400, and requires translating the center by half the width and half the height.
size(400,400);
translate(width/2.0, height/2.0);
- determine x points just outside the current display range, e.g. -201 to 201. This will create a spanning line segment.
- for
y = 2x + 1
plug in x=-201 to get (-201, -401) and x=201 to get (201, 403).
- for
y = -x + 4
plug in x=-201 to get (-201, 205) and x=201 to get (201, -197)
- write the line rendering calls:
size(400,400);
translate(width/2.0, height/2.0);
line(-201, -401, 201, 403);
line(-201, 205, 201, -197);
- Next, you teach how to abstract the point finding processing into point functions:
void setup(){
size(400,400);
}
void draw(){
background(255);
translate(width/2.0, height/2.0);
line(-201, f1(-201), 201, f1(201));
line(-201, f2(-201), 201, f2(201));
}
float f1(float x) {
return 2*x + 1;
}
float f2(float x) {
return -x + 4;
}
- Then you show how you can (although you usually shouldn’t) plot every point in a line with a for loop yourself, rather than drawing line segments:
void setup(){
size(400,400);
}
void draw(){
background(255);
translate(width/2.0, height/2.0);
myline1(-width/2.0, width/2.0);
}
void myline1(float x1, float x2){
for(int x=(int)x1; x<x2; x++){
point(x, f1(x));
}
}
float f1(float x) {
return 2*x + 1;
}
- optionally, then use classes to further abstract line equation objects that can draw themselves.
LineEquation eq1, eq2;
void setup(){
size(400,400);
eq1 = new LineEquation(2, 1);
eq2 = new LineEquation(-1, 4);
}
void draw(){
background(255);
translate(width/2.0, height/2.0);
eq1.render(-width/2.0, width/2.0);
eq2.render(-width/2.0, width/2.0);
}
// linear equation in the form y=mx+b
class LineEquation {
float m;
float b;
LineEquation(float m, float b){
this.m = m;
this.b = b;
}
float f(float x){
return m*x + b;
}
void render(float x1, float x2){
float y1 = this.f(x1);
float y2 = this.f(x2);
line(x1, y1, x2, y2);
}
}
These sketches could be made much prettier and easier to read with a grafica-based background of grid lines and labeled axes, but they focus on the minimal code needed to convey the concepts.
The next concept is solving for the intersection. Here, the students are going to learn something different than setting ys equal and solving for x. Instead, they will use the line-line collision detection of two segments defined by end points:
PVector lineLine(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
// calculate the distance to intersection point
float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
// if uA and uB are between 0-1, lines are colliding
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
float intersectionX = x1 + (uA * (x2-x1));
float intersectionY = y1 + (uA * (y2-y1));
return new PVector(intersectionX,intersectionY);
}
return null;
}
We can teach them mathematically WHY this function returns correct results, and what the distance to intersection is – although often for new programmers we initially focus on HOW to use it – adding it as a top level function, or adding it as a class method, then passing it parameters, then using the returned PVector object’s x and y values to draw an ellipse marking the intersection point if it is found (and handling null correctly if it is not found).
LineEquation eq1, eq2;
PVector cross;
void setup(){
size(400,400);
eq1 = new LineEquation(2, 1);
eq2 = new LineEquation(-1, 4);
}
void draw(){
background(255);
translate(width/2.0, height/2.0);
float rng = width/2.0;
eq1.render(-rng, rng);
eq2.render(-rng, rng);
cross = lineLine(
-rng, eq1.f(-rng), rng, eq1.f(rng),
-rng, eq2.f(-rng), rng, eq2.f(rng)
);
if(cross!=null){
fill(0);
ellipse(cross.x, cross.y, 10, 10);
text(cross.x + "," + cross.y, cross.x + 10, cross.y);
}
}
Building up from this to curves could involve curve functions (or classes/objects) and then finding curve-curve intersections by stepping over segments of two functions and checking for collisions.
A graphing calculator app hides how different computer drawing is from algebra. If the goal for the students to work out that logic while writing their own graphing software then even teaching them how to create their own graph paper or labeled axes from scratch might be valuable.