1 /**************************************************************************** 2 Copyright (c) 2008-2010 Ricardo Quesada 3 Copyright (c) 2011-2012 cocos2d-x.org 4 Copyright (c) 2013-2014 Chukong Technologies Inc. 5 Copyright (c) 2009 Valentin Milea 6 7 http://www.cocos2d-x.org 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ****************************************************************************/ 27 28 /** 29 * converts a line to a polygon 30 * @param {Float32Array} points 31 * @param {Number} stroke 32 * @param {Float32Array} vertices 33 * @param {Number} offset 34 * @param {Number} nuPoints 35 */ 36 cc.vertexLineToPolygon = function (points, stroke, vertices, offset, nuPoints) { 37 nuPoints += offset; 38 if (nuPoints <= 1) 39 return; 40 41 stroke *= 0.5; 42 var idx; 43 var nuPointsMinus = nuPoints - 1; 44 for (var i = offset; i < nuPoints; i++) { 45 idx = i * 2; 46 var p1 = cc.p(points[i * 2], points[i * 2 + 1]); 47 var perpVector; 48 49 if (i === 0) 50 perpVector = cc.pPerp(cc.pNormalize(cc.pSub(p1, cc.p(points[(i + 1) * 2], points[(i + 1) * 2 + 1])))); 51 else if (i === nuPointsMinus) 52 perpVector = cc.pPerp(cc.pNormalize(cc.pSub(cc.p(points[(i - 1) * 2], points[(i - 1) * 2 + 1]), p1))); 53 else { 54 var p0 = cc.p(points[(i - 1) * 2], points[(i - 1) * 2 + 1]); 55 var p2 = cc.p(points[(i + 1) * 2], points[(i + 1) * 2 + 1]); 56 57 var p2p1 = cc.pNormalize(cc.pSub(p2, p1)); 58 var p0p1 = cc.pNormalize(cc.pSub(p0, p1)); 59 60 // Calculate angle between vectors 61 var angle = Math.acos(cc.pDot(p2p1, p0p1)); 62 63 if (angle < cc.degreesToRadians(70)) 64 perpVector = cc.pPerp(cc.pNormalize(cc.pMidpoint(p2p1, p0p1))); 65 else if (angle < cc.degreesToRadians(170)) 66 perpVector = cc.pNormalize(cc.pMidpoint(p2p1, p0p1)); 67 else 68 perpVector = cc.pPerp(cc.pNormalize(cc.pSub(p2, p0))); 69 } 70 perpVector = cc.pMult(perpVector, stroke); 71 72 vertices[idx * 2] = p1.x + perpVector.x; 73 vertices[idx * 2 + 1] = p1.y + perpVector.y; 74 vertices[(idx + 1) * 2] = p1.x - perpVector.x; 75 vertices[(idx + 1) * 2 + 1] = p1.y - perpVector.y; 76 } 77 78 // Validate vertexes 79 offset = (offset === 0) ? 0 : offset - 1; 80 for (i = offset; i < nuPointsMinus; i++) { 81 idx = i * 2; 82 var idx1 = idx + 2; 83 84 var v1 = cc.vertex2(vertices[idx * 2], vertices[idx * 2 + 1]); 85 var v2 = cc.vertex2(vertices[(idx + 1) * 2], vertices[(idx + 1) * 2 + 1]); 86 var v3 = cc.vertex2(vertices[idx1 * 2], vertices[idx1 * 2]); 87 var v4 = cc.vertex2(vertices[(idx1 + 1) * 2], vertices[(idx1 + 1) * 2 + 1]); 88 89 //BOOL fixVertex = !ccpLineIntersect(ccp(p1.x, p1.y), ccp(p4.x, p4.y), ccp(p2.x, p2.y), ccp(p3.x, p3.y), &s, &t); 90 var fixVertexResult = !cc.vertexLineIntersect(v1.x, v1.y, v4.x, v4.y, v2.x, v2.y, v3.x, v3.y); 91 if (!fixVertexResult.isSuccess) 92 if (fixVertexResult.value < 0.0 || fixVertexResult.value > 1.0) 93 fixVertexResult.isSuccess = true; 94 95 if (fixVertexResult.isSuccess) { 96 vertices[idx1 * 2] = v4.x; 97 vertices[idx1 * 2 + 1] = v4.y; 98 vertices[(idx1 + 1) * 2] = v3.x; 99 vertices[(idx1 + 1) * 2 + 1] = v3.y; 100 } 101 } 102 }; 103 104 /** 105 * returns whether or not the line intersects 106 * @param {Number} Ax 107 * @param {Number} Ay 108 * @param {Number} Bx 109 * @param {Number} By 110 * @param {Number} Cx 111 * @param {Number} Cy 112 * @param {Number} Dx 113 * @param {Number} Dy 114 * @return {Object} 115 */ 116 cc.vertexLineIntersect = function (Ax, Ay, Bx, By, Cx, Cy, Dx, Dy) { 117 var distAB, theCos, theSin, newX; 118 119 // FAIL: Line undefined 120 if ((Ax === Bx && Ay === By) || (Cx === Dx && Cy === Dy)) 121 return {isSuccess:false, value:0}; 122 123 // Translate system to make A the origin 124 Bx -= Ax; 125 By -= Ay; 126 Cx -= Ax; 127 Cy -= Ay; 128 Dx -= Ax; 129 Dy -= Ay; 130 131 // Length of segment AB 132 distAB = Math.sqrt(Bx * Bx + By * By); 133 134 // Rotate the system so that point B is on the positive X axis. 135 theCos = Bx / distAB; 136 theSin = By / distAB; 137 newX = Cx * theCos + Cy * theSin; 138 Cy = Cy * theCos - Cx * theSin; 139 Cx = newX; 140 newX = Dx * theCos + Dy * theSin; 141 Dy = Dy * theCos - Dx * theSin; 142 Dx = newX; 143 144 // FAIL: Lines are parallel. 145 if (Cy === Dy) return {isSuccess:false, value:0}; 146 147 // Discover the relative position of the intersection in the line AB 148 var t = (Dx + (Cx - Dx) * Dy / (Dy - Cy)) / distAB; 149 150 // Success. 151 return {isSuccess:true, value:t}; 152 }; 153 154 /** 155 * returns wheter or not polygon defined by vertex list is clockwise 156 * @param {Array} verts 157 * @return {Boolean} 158 */ 159 cc.vertexListIsClockwise = function(verts) { 160 for (var i = 0, len = verts.length; i < len; i++) { 161 var a = verts[i]; 162 var b = verts[(i + 1) % len]; 163 var c = verts[(i + 2) % len]; 164 165 if (cc.pCross(cc.pSub(b, a), cc.pSub(c, b)) > 0) 166 return false; 167 } 168 169 return true; 170 };