1 //= require 'point.class'
  2 
  3 (function() {
  4   
  5   /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */
  6   
  7   var global = this,
  8       fabric = global.fabric || (global.fabric = { });
  9   
 10   if (fabric.Intersection) {    
 11     fabric.warn('fabric.Intersection is already defined');
 12     return;
 13   }
 14   
 15   /**
 16    * @class Intersection
 17    * @memberOf fabric
 18    */
 19   function Intersection(status) {
 20     if (arguments.length > 0) {
 21       this.init(status);
 22     }
 23   }
 24   
 25   fabric.Intersection = Intersection;
 26   
 27   fabric.Intersection.prototype = /** @scope fabric.Intersection.prototype */ {
 28     
 29     /**
 30      * @method init
 31      * @param {String} status
 32      */
 33     init: function (status) {
 34       this.status = status;
 35       this.points = [];
 36     },
 37     
 38     /**
 39      * @method appendPoint
 40      * @param {String} status
 41      */
 42     appendPoint: function (point) {
 43       this.points.push(point);
 44     },
 45     
 46     /**
 47      * @method appendPoints
 48      * @param {String} status
 49      */
 50     appendPoints: function (points) {
 51       this.points = this.points.concat(points);
 52     }
 53   };
 54   
 55   /**
 56    * @static
 57    * @method intersectLineLine
 58    */
 59   fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) {
 60     var result,
 61         ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),
 62         ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),
 63         u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
 64     if (u_b != 0) {
 65       var ua = ua_t / u_b,
 66           ub = ub_t / u_b;
 67       if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {
 68         result = new Intersection("Intersection");
 69         result.points.push(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)));
 70       }
 71       else {
 72         result = new Intersection("No Intersection");
 73       }
 74     }
 75     else {
 76       if (ua_t == 0 || ub_t == 0) {
 77         result = new Intersection("Coincident");
 78       }
 79       else {
 80         result = new Intersection("Parallel");
 81       }
 82     }
 83     return result;
 84   };
 85   
 86   /**
 87    * @method intersectLinePolygon
 88    */
 89   fabric.Intersection.intersectLinePolygon = function(a1,a2,points){
 90     var result = new Intersection("No Intersection"),
 91         length = points.length;
 92         
 93     for (var i = 0; i < length; i++) {
 94       var b1 = points[i],
 95           b2 = points[(i+1) % length],
 96           inter = Intersection.intersectLineLine(a1, a2, b1, b2);
 97           
 98       result.appendPoints(inter.points);
 99     }
100     if (result.points.length > 0) {
101       result.status = "Intersection";
102     }
103     return result;
104   };
105   
106   /**
107    * @method intersectPolygonPolygon
108    */
109   fabric.Intersection.intersectPolygonPolygon = function (points1, points2) {
110     var result = new Intersection("No Intersection"),
111         length = points1.length;
112         
113     for (var i = 0; i < length; i++) {
114       var a1 = points1[i],
115           a2 = points1[(i+1) % length],
116           inter = Intersection.intersectLinePolygon(a1, a2, points2);
117           
118       result.appendPoints(inter.points);
119     }
120     if (result.points.length > 0) {
121       result.status = "Intersection";
122     }
123     return result;
124   };
125   
126   /**
127    * @method intersectPolygonRectangle
128    */
129   fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) {
130     var min = r1.min(r2),
131         max = r1.max(r2),
132         topRight = new fabric.Point(max.x, min.y),
133         bottomLeft = new fabric.Point(min.x, max.y),
134         inter1 = Intersection.intersectLinePolygon(min, topRight, points),
135         inter2 = Intersection.intersectLinePolygon(topRight, max, points),
136         inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points),
137         inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points),
138         result = new Intersection("No Intersection");
139         
140     result.appendPoints(inter1.points);
141     result.appendPoints(inter2.points);
142     result.appendPoints(inter3.points);
143     result.appendPoints(inter4.points);
144     if (result.points.length > 0) {
145       result.status="Intersection";
146     }
147     return result;
148   };
149   
150 })();