function Segment(x, y) { if (x < y) { this.x = x; this.y = y; } else { this.x = y; this.y = x; } } Segment.prototype.length = function () { return (this.y - this.x); } Segment.prototype.before = function (s) { return (this.x < s.x); } // Returns the intersection of segments s1 and s2 // or null is it doesn't exist Segment.intersection = function (s1, s2) { if (s2.before(s1)) { tmp = s1; s1 = s2; s2 = tmp; } if (s1.y < s2.x) { // No intersection return null; } else { return new Segment(s2.x, Math.min(s1.y, s2.y)); } } function Point(x, y) { this.x = x; this.y = y; } // A rectangle is defined by its left corner p0, // its length dx and high dy function Rectangle(p0, dx, dy) { this.p0 = p0; this.dx = dx; this.dy = dy; } Rectangle.prototype.lowerEdge = function () { return new Segment(this.p0.x, this.p0.x + this.dx); } Rectangle.prototype.leftEdge = function () { return new Segment(this.p0.y, this.p0.y + this.dy); } // s1 should be the lower edge and s2 the left one. // And they *must* shape a rectangle Rectangle.fromSegments = function (s1, s2) { return new Rectangle(new Point(s1.x, s2.x), s1.length(), s2.length()); } // Return the intersection of r1 and r2 // or null is it doesn't exist Rectangle.intersection = function (r1, r2) { var sleft = Segment.intersection(r1.leftEdge(), r2.leftEdge()); var slower = Segment.intersection(r1.lowerEdge(), r2.lowerEdge()); if (sleft == null || slower == null) { return new Rectangle(new Point(0,0), 0, 0); } else { return Rectangle.fromSegments(slower, sleft); } } Rectangle.prototype.area = function () { return this.dx * this.dy; }