Here's a Processing sketch that allows users to draw circles and line segments for geometric constructions.
boolean lineMode;
boolean circleMode;
boolean dragMode;
boolean last_shape_line;
boolean last_shape_circle;
boolean mouse_Is_Pressed;
int xSize = 1200;
int ySize = 640;
int clicknumber;
int numberoflines=0;
int numberofcircles =0;
Circle[] circles;
Line[] lines;
float startX=0;
float startY=0;
float releaseX=0;
float releaseY=0;
class Circle {
float x, y, radius;
Circle(float xpos, float ypos, float r) {
x = xpos;
y = ypos;
radius = r;
}
void display() {
ellipse(x, y, radius*2, radius*2);
point(x,y);
}
}
class Line {
float x1, y1, x2, y2;
Line(float xStart, float yStart, float xEnd, float yEnd) {
x1 = xStart;
y1 = yStart;
x2 = xEnd;
y2 = yEnd;
}
void display() {
line(x1, y1, x2, y2);
}
}
void mouseClicked() {
if (circleMode && clicknumber == 1){
circleMode = false;
releaseX = mouseX;
releaseY = mouseY;
circles[numberofcircles] = new Circle(startX,startY, sqrt(pow(mouseX-startX,2)+pow(mouseY-startY,2)));
numberofcircles +=1;
clicknumber = 0;
last_shape_circle = true;
last_shape_line = false;
}
if (lineMode && clicknumber == 1){
lineMode = false;
releaseX = mouseX;
releaseY = mouseY;
lines[numberoflines] = new Line(startX,startY,releaseX,releaseY);
numberoflines +=1;
clicknumber = 0;
last_shape_line = true;
last_shape_circle = false;
}
if ((circleMode || lineMode) && clicknumber == 0){
startX = mouseX;
startY = mouseY;
clicknumber = 1;
}
}
void setup() {
size(1200, 640, P3D);
circles = new Circle[1000];
lines = new Line[1000];
}
void keyPressed() {
if (key == 'd') {
if (!dragMode && !circleMode && !lineMode) {
dragMode = true;
}
}
if (key == 'l') {
if (!circleMode) {
lineMode = true;
clicknumber = 0;
}
}
if (key == 'c') {
if (!lineMode) {
circleMode = true;
clicknumber = 0;
}
}
if (key =='e') {
circleMode = false;
lineMode = false;
}
if (key =='u') {
if (last_shape_line && numberoflines>0) {
lines[numberoflines-1] = null;
numberoflines += -1;
last_shape_line = false;
}
if (last_shape_circle && numberofcircles > 0) {
circles[numberofcircles-1] = null;
numberofcircles+=-1;
last_shape_circle = false;
}
}
}
void draw() {
if (dragMode) {
fill(255);
text("drag", mouseX+10, mouseY+10, 300,300);
noFill();
}
background(0);
if (lineMode) {
text("line", mouseX+10, mouseY+10, 300,300);
if (clicknumber>0){
strokeWeight(1);
line(startX,startY,mouseX,mouseY);
}
}
if (circleMode) {
text("circle", mouseX+10, mouseY+10, 300,300);
if (clicknumber>0){
line(startX,startY,mouseX,mouseY);
strokeWeight(3);
ellipse(startX,startY,2*sqrt(pow(mouseX-startX,2)+pow(mouseY-startY,2)),2*sqrt(pow(mouseX-startX,2)+pow(mouseY-startY,2)));
strokeWeight(1);
}
}
noFill();
stroke(255);
strokeWeight(3);
for (int i=0; i<numberofcircles; i=i+1){
circles[i].display();
}
for (int i=0; i<numberoflines; i=i+1){
lines[i].display();
}
text("press 'c' to draw a circle", 10, 10, 300, 20 );
text("press 'l' to draw a line", 10, 30, 300, 20 );
text("press 'u' to undo the last shape", 10, 50, 300, 20 );
}
If you want to focus on programming in the curriculum, you might consider exposing your students to methods of proof that are altogether different than what you may have been using in the past by teaching them to do computational coordinate proofs using symbolic variables. Processing can compile Python, which is excellent for symbolic and numerical computing. You can work with them on expressing theorems and "given" statements in terms of symbolic quantities, then use the equivalence operator to determine equivalence with the "result" statements. Here's an example for the theorem "In an isosceles triangle, the base angles are congruent." You'll have to coach the students to (1) generate the appropriate symbolic coordinates, and (2) generate the appropriate symbolic statement of equivalence, then (3) implement these into a computational proof. Ideally, you'll be developing programs as you go along so, so most of the work represented by the sketch below would already be done and just copied in from a class workflow file. In order to run this sketch, you'll have to copy the numpy and sympy modules into the sketch directory and install the Python compiler in your Processing IDE. Here is the proof:
import numpy
import sympy
def add(u,v):
#computes the sum of vectors u,v
sum = [0]*len(u)
for i in range(len(u)):
sum[i] = u[i] + v[i]
return sum
def subtract(u,v):
#computes the difference of vectors u,v
return [u[0]-v[0],u[1]-v[1]]
def dot(u,v):
# computes the dot product of u anv v.
return u[0]*v[0] + u[1]*v[1]
def length(u):
# computes the length of vector u
return dot(u,u)**(0.5)
def angle(p,q,r):
# returns the measure of angle pqr for points p = [p[0],p[1]], q = [q[0],q[1]], r = [r[0],r[1]]
u = subtract(p,q)
v = subtract(r,q)
return sympy.acos(dot(u,v)/ (length(u)*length(v)) )
# In order to prove this statement, construct an arbitrary isosceles triangle PQR and then
# prove that it has the desired property. Triangle PQR will have a base of length b and a
# height of length h.
#(1) Define any symbolic variables you will use in your proof:
b = sympy.symbols('b')
h = sympy.symbols('h')
#(2) Assign coordinates to determine your isosceles triangle:
P = [-b/2, 0]
Q = [0,h]
R = [b/2, 0]
#(2.5, optional) Demonstrate that your triangle is indeed isosceles:
length(subtract(P,Q)) == length(subtract(R,Q))
#(3) The base angles for this triangle are angle QPR and angle QRP, so we want to show
# that both angles have the same measure. We will use the function we've already
# written to give the angles. If the statement is true, the compiler will print "true".
if angle(Q,P,R) == angle(Q,R,P):
print("true")
else:
print("false")
When students run the sketch, Processing will return "True" in the console. Quod erat demonstrandum. This scheme should in principle work for any geometric proof that your students encounter.
Many students will have difficulties with the notion of an "arbitrary" representative object, but I find that once they become familiar with assigning symbolic coordinates (which is already a part of most elementary geometry curricula), and you tell them that's what constitutes a proof, as opposed to giving a concrete example, (and that you won't give any points for the latter...) they do okay. If they've worked with objects in Java then they should be better primed for abstraction in mathematics, I think.