Line Test Demo

While entangled in the bowels of a diseased telecon I decided to make good use of my time and wrote this simple test:

Click, drag, and release to draw a new line. The text will (should?!) indicate whether or not the two points are on the same side of the line or not.

The demo uses some basic Phaser features for the interaction and drawing. Really though it’s just quadruple checking a basic calculation:

(Bx – Ax) * (Cy – Ay) – (By – Ay) * (Cx – Ax)

Where the line is defined by (Ax,Ay)–(Bx,By) and a point is (Cx, Cy). The value will be 0 if the point is on the line, and otherwise negative or positive depending on which side of the line it is on. The specific sign depends on the orientation of the line, but you can compare the sign for two points to determine if they’re on the same side or not. That can be boiled down into a single calculation. However, testing if four points are on the same side is a key part of a simple line/rectangle intersection test. For that use it seemed simpler to just calculate each separately.

The full Javascript code is:

var game = new Phaser.Game(530, 300, Phaser.AUTO, 'gamecontainer',
                           { create: create, update: update, render: render });

var line;
var setting = false;

var point1;
var point2;

var textSame;
var textDiff;


function create() {

  line = new Phaser.Line(game.world.width/4, game.world.height/4,
                         3*game.world.width/4, 3*game.world.height/4);

  point1 = new Phaser.Point(game.world.width/2, game.world.height/4);
  point2 = new Phaser.Point(game.world.width/2, 3*game.world.height/4);

  textSame = game.add.text(4, 0, "Same Side", { fill: '#ffffff' });
  textSame.visible = false;

  textDiff = game.add.text(0, 0, "Different Side", { fill: '#ffffff' });
  textDiff.visible = false;

  game.input.onDown.add(click, this);

  setting = true;

}

function update() {

  if (setting) {
    if (game.input.activePointer.isDown) {
      line.end.set(game.input.activePointer.x, game.input.activePointer.y);
    } else {
      setting = false;

        var sign1 =
            (line.end.x - line.start.x) * (point1.y - line.start.y) -
            (line.end.y - line.start.y) * (point1.x - line.start.x);

        var sign2 =
            (line.end.x - line.start.x) * (point2.y - line.start.y) -
            (line.end.y - line.start.y) * (point2.x - line.start.x);

        console.log("Signs are " + sign1 + "  " + sign2);

        if ((sign1<0 && sign2<0) ||
            (sign1>0 && sign2>0) ||
            (sign1==0 && sign2==0)) {

            textSame.visible = true;
            textDiff.visible = false;

        } else {
            textSame.visible = false;
            textDiff.visible = true;
        }
    }
  }
}

function click(pointer) {
  setting = true;
  line.start.set(pointer.x, pointer.y);
}

function render() {
  game.debug.geom(line);
  game.debug.geom(point1, '#ff0000');
  game.debug.geom(point2, '#ff0000');
}