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