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