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