6
$\begingroup$

My supervisors want to see coding integrated into the ninth grade Geometry class. This class is mostly concerned with proofs--not too much algebra. These students know a decent amount of the visually oriented language: Processing.

How can I integrate their coding ability into the geometry class as a project?

$\endgroup$
  • 4
    $\begingroup$ I'm willing to bet that this came from some sort of telephone-style passing along of one of the following two sources: The original, David Mumford's blog (see the 7th bullet point) or Jordan Ellenberg's commentary on said post/paper. $\endgroup$ – pjs36 Dec 6 '15 at 14:51
  • 3
    $\begingroup$ @pjs36: Interesting link. To be clear for those who don't follow it, the suggestion there is essentially to have a programming course replace the geometry course. $\endgroup$ – Daniel R. Collins Dec 6 '15 at 18:50
  • 1
    $\begingroup$ I purged comments as there were many obsolete ones around clarification of the question. Please let me know if you feel some piece of information needs to be restored. $\endgroup$ – quid Dec 9 '15 at 22:10
  • 1
    $\begingroup$ I've significantly edited my answer. Take a look! $\endgroup$ – Andrew Jun 25 '16 at 0:09
3
$\begingroup$

Here is one idea for a project. Have them implement Descartes' Theorem on four tangent circles: Given three tangent circles, the theorem can be used to construct a fourth:


4TangentCircs
          (Image from Wikipedia.)
You could start with the special case when one of the first three circles has an infinite radius and so is a straight line. Then only two tangent circles touching that line are needed to get started.

So a separate problem is: Given $r_1$ and $r_2$, construct two circles with those radii tangent to each other and resting on the $x$-axis. That seems accessible to $9^\textrm{th}$ graders.

This allows the project to start with a relatively easy part, move on to the more challenging general case, and you might entice them beyond with the Apollonian gasket:


          enter image description here
          (Image from Wikipedia.)
The project would require using Processing's line( ) and ellipse( ) functions, as well as some algebraic calculations.

$\endgroup$
  • 2
    $\begingroup$ @Andrew: The OP asked for ideas on how to integrate coding in a $9^\textrm{th}$-grade geometry class, not whether or not to do so. The premise was that the students already know a decent amount of the language Processing. In any case, No, I do not think it is convoluted. $\endgroup$ – Joseph O'Rourke Dec 18 '15 at 17:34
3
$\begingroup$

I hope I'm not too late to offer some resources. I wrote a book, Hacking Math Class with Python, to promote the use of programming in math education in high school and beyond, and I'm also a big fan of Processing and p5.js for learning math using art, games and interactive, dynamic graphics.

I've posted a bunch of sketches on openprocessing.org which I did with students at my Coder School and on my own. Lots of fractals and stuff borrowed from books. Here's the portfolio:

http://www.openprocessing.org/user/49425

A couple of dozen tutorials on my YouTube channel, but most are in Python:

https://www.youtube.com/user/1houraweekmathclass/videos

$\endgroup$
2
$\begingroup$

I misread the question, and this doesn't answer it (because Dopapp specificially wants to use the Processing language). But I will leave it here for the links.


(1) The Khan Academy has 10 drawing and animation projects based on JavaScript. See their curriculum at this link.

(2) Scratch is even easier to learn than JavaScript. Some intro projects can be found at Eutopia's link.

(3) Then there is Geogebra, with a broad community and many resources available. Maybe start at this link.

(4) Geometer's Sketchpad, dynamic geometry software. (Thanks to user celeriko). They have curricula and considerable supporting resources provided by McGraw-Hill.

(5) Cinderella: Powerful dynamic geometry software, used widely in Germany and Japan, perhaps too sophisticated for your purposes.


          Cinderalla


$\endgroup$
  • 1
    $\begingroup$ in line with geogebra is Geometer's Sketchpad,another very well designed dynamic geometry package $\endgroup$ – celeriko Dec 5 '15 at 4:42
  • $\begingroup$ @celeriko: Thanks, that was an oversight, now corrected. $\endgroup$ – Joseph O'Rourke Dec 5 '15 at 12:33
  • 1
    $\begingroup$ Geometer's Sketchpad is likely to be mentioned in a modern Geometry textbook, but it is not cheap. Geogebra does almost all the same things, though often in a different way: what is easy in one is not as easy in the other. $\endgroup$ – Rory Daulton Dec 5 '15 at 13:21
  • $\begingroup$ @Dopapp: Sorry, I totally missed that you specified the language Processing. My mistake. This requires a rather different answer. I can see that schools, such as Trinity Valley in Texas, offer a Geometry course using Processing and Geometer's Sketchpad, but I didn't find details. $\endgroup$ – Joseph O'Rourke Dec 5 '15 at 19:43
1
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ 1) This answer would be easier to understand with the code only visible in previous edits, and replaced by a summary here. 2) What happens when you ask Processing whether sympy.asin(-x) == -sympy.asin(x)? I'd be surprised if it returns True on all simple identities, so I'd be surprised if this notion of constituting a proof is sufficient. $\endgroup$ – user173 Jun 25 '16 at 2:13
  • $\begingroup$ 1) The code was changed in the most recent edit. I don't follow what you mean by "easier to understand". 2) It returns "True." I don't understand what you mean by "constituting a proof is sufficient". $\endgroup$ – Andrew Jun 25 '16 at 14:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.