Code

float iota;
float nan = 1.0/0.0;
float[][] p = new float[][] {{nan,nan},{nan,nan},{nan,nan},{nan,nan}};
float[] pSect = new float[2];
int holding=-1;
int holdRadius = 6;
float ua;
float ub;
float denom;

void setup()
{
  size(400,400);
  smooth();
  noFill();
  rectMode(CENTER_DIAMETER);
  ellipseMode(CENTER_DIAMETER);
}

void mousePressed()
{
  int i;
  //Are we dropping a point?
  if (holding != -1)
  {
    holding = -1;
    return;
  }
  //Are we defining a new point?
  for (i=0; i<4; i++)
    if (p[i][0]==nan)
    {
      p[i][0]=mouseX;
      p[i][1]=mouseY;
      return;
    }
  //Are we grabbing a point?
  for (i=0; i<4; i++)
    if (abs(p[i][0]-mouseX)<holdRadius && abs(p[i][1]-mouseY)<holdRadius)
    {
      holding=i;
      return;
    }
}

void drawIfDefined(int n)
{
  n *= 2;
  if (p[n][0]!=nan && p[n+1][0]!=nan)
  {
    stroke(155);
    line(p[n][0],p[n][1],p[n+1][0],p[n+1][1]);
    stroke(0,255,0);
    rect(p[n][0],p[n][1],holdRadius,holdRadius);
    rect(p[n+1][0],p[n+1][1],holdRadius,holdRadius);
  }
}

boolean drawIntersection()
//Returns an intersection flag
{
  //calculate numerators and denominators
  ua    = (p[3][0]-p[2][0])*(p[0][1]-p[2][1]) - (p[3][1]-p[2][1])*(p[0][0]-p[2][0]);
  ub    = (p[1][0]-p[0][0])*(p[0][1]-p[2][1]) - (p[1][1]-p[0][1])*(p[0][0]-p[2][0]);
  denom = (p[3][1]-p[2][1])*(p[1][0]-p[0][0]) - (p[3][0]-p[2][0])*(p[1][1]-p[0][1]);  
  if (denom != 0)
  {
    //Neither parallel nor coincident
    ua /= denom;
    ub /= denom;
    if (ua <= 1 && ub <= 1 && ua >= 0 && ub >= 0)
    {
      pSect[0]=p[0][0] + ua*(p[1][0]-p[0][0]);
      pSect[1]=p[0][1] + ua*(p[1][1]-p[0][1]);
      fill(0,255,0);
      stroke(0,255,0);
      ellipse(pSect[0],pSect[1],holdRadius,holdRadius);
      noFill();
      return true;
    }
  }
  return false;
}

void loop()
{
  int i;
  float ratio,tx,ty;
  background(0,0,50);
  if (holding != -1)
  {
    p[holding][0]=mouseX;
    p[holding][1]=mouseY;
  }
  drawIfDefined(0);
  drawIfDefined(1);
  if(drawIntersection())
  {
       iota = (millis()%2000);
       ratio = iota/2000.0;
       fill(0,ratio*255,0);
       stroke(0,ratio*255,0);
       for (i=0; i<4; i++)
       {
         tx=(1.0-ratio)*p[i][0]+ratio*pSect[0];
         ty=(1.0-ratio)*p[i][1]+ratio*pSect[1];
         ellipse(tx,ty,holdRadius,holdRadius);
       }
       noFill();
  }
}

021 -- Finding Line-Line Intersections: Implementing an algorithm

Statement:Create a 400x400 pixel applet which records 4 of the user's clicks. Using these 4 points (e.g. A,B,C,D), construct 2 lines from points AB and CD. Using the Web as your research tool (hint: Paul Bourke), compute the coordinates (if any) at which the two lines intersect. If the intersection point exists, draw a small circle at that location. Allow the user to pick up and continuously move a line's endpoint if the cursor is sufficiently close enough. (Although it is not required, consider storing the points in a 2D float array.)

Optional challenges for advanced students: 1. can you design an interaction that allows lines to be "broken" at their intersection points, thus creating new lines? 2. What about allowing users to specify two Bezier curves (with 4 control points each), and finding the intersections of these?
Simple Line Intersection

hide statement