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 })();