1// ---------------------------------------------------------------------------------------------------------------- 2// Rectangle 3// ---------------------------------------------------------------------------------------------------------------- 4var lastRectAppearance = new Appearance("#900090", 1, 2); 5 6function Rectangle(center) 7{ 8 this.scene = null; 9 this.points = [ center.copy(), center.copy(), center.copy(), center.copy() ]; 10 this.rows = 1; 11 this.columns = 1; 12 this.selected = false; 13 this.visible = true; 14 this.frozen = false; 15 this.appearance = lastRectAppearance.copy(); 16 this.centerPoints = false; 17 this.onChangeListeners = []; 18 this.boundsMin = new Vector(Number.MAX_VALUE,Number.MAX_VALUE); 19 this.boundsMax = new Vector(-Number.MAX_VALUE,-Number.MAX_VALUE); 20 21 this.getBoundsMin = function() 22 { 23 return this.boundsMin; 24 } 25 26 this.getBoundsMax = function() 27 { 28 return this.boundsMax; 29 } 30 31 this.saveAsJavascript = function() 32 { 33 var str = "var rectObj = new Rectangle("; 34 35 str += "new Vector(0,0)"; 36 str += ");\n"; 37 38 str += "rectObj.points[0] = new Vector(" + this.points[0].x + ", " + this.points[0].y + ");\n"; 39 str += "rectObj.points[1] = new Vector(" + this.points[1].x + ", " + this.points[1].y + ");\n"; 40 str += "rectObj.points[2] = new Vector(" + this.points[2].x + ", " + this.points[2].y + ");\n"; 41 str += "rectObj.points[3] = new Vector(" + this.points[3].x + ", " + this.points[3].y + ");\n"; 42 str += this.appearance.saveAsJavascript("rectObj"); 43 str += "rectObj.rows = " + this.rows + ";\n"; 44 str += "rectObj.columns = " + this.columns + ";\n"; 45 str += "rectObj.centerPoints = " + this.centerPoints + ";\n"; 46 str += "rectObj.visible = " + this.visible + ";\n"; 47 str += "rectObj.frozen = " + this.frozen + ";\n"; 48 49 if (this.name != undefined) 50 { 51 str += "rectObj.name = \"" + this.name + "\";\n"; 52 } 53 54 str += "rectObj.onChange();\n"; 55 56 str += "scene.addObject(rectObj);\n"; 57 return str; 58 } 59 60 this.addChangeListener = function (listener) 61 { 62 this.onChangeListeners.push(listener); 63 } 64 65 this.onChange = function(changeDetails) 66 { 67 // Backwards compatibility 68 this.appearance.SetFromOldProperties(this); 69 70 lastRectAppearance = this.appearance.copy(); 71 72 var center = avg(this.points[0], this.points[2]); 73 var halfSize = abs(sub(this.points[0], center)); 74 75 this.boundsMin = sub(center, halfSize); 76 this.boundsMax = add(center, halfSize); 77 78 for (var i = 0; i != this.onChangeListeners.length; ++i) 79 { 80 this.onChangeListeners[i](this, changeDetails); 81 } 82 } 83 84 this.setSize = function(w,h) 85 { 86 var half = new Vector(w*0.5, h*0.5); 87 88 var center = avg(this.points[0], this.points[2]); 89 90 this.points[0] = add(center, new Vector(-w*0.5, +h*0.5)); 91 this.points[1] = add(center, new Vector(+w*0.5, +h*0.5)); 92 this.points[2] = add(center, new Vector(+w*0.5, -h*0.5)); 93 this.points[3] = add(center, new Vector(-w*0.5, -h*0.5)); 94 95 this.onChange(); 96 } 97 98 this.draw = function(camera) 99 { 100 camera.drawLineStrip(this.points, true, this.appearance.GetLineColor(), this.appearance.GetLineWidth(this.selected), this.appearance.GetLineDash(), this.appearance.GetFillColor(), this); 101 102 if (this.rows > 1 || this.columns > 1) 103 { 104 var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns); 105 var deltaX1 = div(sub(this.points[2], this.points[3]), this.columns); 106 var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows); 107 var deltaY1 = div(sub(this.points[2], this.points[1]), this.rows); 108 109 var points = []; 110 111 for (var i = 1; i <= this.columns - 1; ++i) 112 { 113 var pX0 = mad(deltaX0, i, this.points[0]); 114 var pX1 = mad(deltaX1, i, this.points[3]); 115 116 points.push(pX0); 117 points.push(pX1); 118 } 119 120 for (var i = 1; i <= this.rows - 1; ++i) 121 { 122 var pY0 = mad(deltaY0, i, this.points[0]); 123 var pY1 = mad(deltaY1, i, this.points[1]); 124 125 points.push(pY0); 126 points.push(pY1); 127 } 128 129 camera.drawLines(points, this.appearance.GetLineColor(), this.appearance.GetLineWidth(this.selected), [], this.appearance.GetFillColor(), this); 130 } 131 132 if (this.centerPoints) 133 { 134 var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns); 135 var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows); 136 137 for (var i = 0.5; i <= this.columns; i += 1) 138 { 139 var pX = mad(deltaX0, i, this.points[0]); 140 141 for (var j = 0.5; j <= this.rows; j += 1) 142 { 143 var pY = mad(deltaY0, j, pX); 144 145 camera.drawCross(pY, camera.invScale(5), 0, "#808080", 2); 146 } 147 } 148 } 149 } 150 151 this.hitTest = function(a, b, camera) 152 { 153 if ( overlapRectLine(a, b, this.points[0], this.points[1]) || 154 overlapRectLine(a, b, this.points[1], this.points[2]) || 155 overlapRectLine(a, b, this.points[2], this.points[3]) || 156 overlapRectLine(a, b, this.points[3], this.points[0])) 157 { 158 return true; 159 } 160 161 if (this.rows > 1 || this.columns > 1) 162 { 163 var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns); 164 var deltaX1 = div(sub(this.points[2], this.points[3]), this.columns); 165 var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows); 166 var deltaY1 = div(sub(this.points[2], this.points[1]), this.rows); 167 168 for (var i = 1; i <= this.columns - 1; ++i) 169 { 170 var pX0 = mad(deltaX0, i, this.points[0]); 171 var pX1 = mad(deltaX1, i, this.points[3]); 172 173 if (overlapRectLine(a, b, pX0, pX1)) 174 return true; 175 } 176 177 for (var i = 1; i <= this.rows - 1; ++i) 178 { 179 var pY0 = mad(deltaY0, i, this.points[0]); 180 var pY1 = mad(deltaY1, i, this.points[1]); 181 182 if (overlapRectLine(a, b, pY0, pY1)) 183 return true; 184 } 185 } 186 187 if (this.appearance.fillAlpha > 0) 188 { 189 if ( b.x<this.points[0].x || 190 a.x>this.points[2].x || 191 b.y<this.points[2].y || 192 a.y>this.points[0].y) 193 { 194 return false;
195 } 196 197 return true; 198 } 199 200 return false; 201 } 202 203 this.getSnapPoints = function() 204 { 205 var points = [ { type: "node", p: this.points[0] }, 206 { type: "node", p: this.points[1] }, 207 { type: "node", p: this.points[2] }, 208 { type: "node", p: this.points[3] }, 209 { type: "midpoint", p: avg(this.points[0], this.points[1]) }, 210 { type: "midpoint", p: avg(this.points[1], this.points[2]) }, 211 { type: "midpoint", p: avg(this.points[2], this.points[3]) }, 212 { type: "midpoint", p: avg(this.points[3], this.points[0]) }, 213 { type: "center", p: avg(this.points[0], this.points[2]) } ]; 214 215 if (this.rows > 1 || this.columns > 1) 216 { 217 var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns); 218 var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows); 219 220 for (var i = 0; i <= this.columns; ++i) 221 { 222 var pX = mad(deltaX0, i, this.points[0]); 223 224 for (var j = 0; j <= this.rows; ++j) 225 { 226 var pY = mad(deltaY0, j, pX); 227 228 if ( ((i == 0 || i == (this.columns)) && (j>0 && j<this.rows)) || 229 ((j == 0 || j == (this.rows)) && (i>0 && i<this.columns)) ) 230 { 231 points.push({type: "node", p: pY }); 232 } 233 else if ( (i>0 && i<this.columns) && (j>0 && j<this.rows) ) 234 { 235 points.push({type: "intersection", p: pY }); 236 } 237 } 238 } 239 } 240 241 242 if (this.centerPoints) 243 { 244 var deltaX0 = div(sub(this.points[1], this.points[0]), this.columns); 245 var deltaY0 = div(sub(this.points[3], this.points[0]), this.rows); 246 247 for (var i = 0.5; i <= this.columns; i += 1) 248 { 249 var pX = mad(deltaX0, i, this.points[0]); 250 251 for (var j = 0.5; j <= this.rows; j += 1) 252 { 253 var pY = mad(deltaY0, j, pX); 254 255 points.push({type: "node", p: pY }); 256 } 257 } 258 } 259 260 return points; 261 } 262 263 this.getDragPoints = function(localSpace, camera) 264 { 265 if (this.isFrozen()) 266 return []; 267 268 var points = [ this.points[0], 269 this.points[1], 270 this.points[2], 271 this.points[3], 272 avg(this.points[0], this.points[1]), 273 avg(this.points[1], this.points[2]), 274 avg(this.points[2], this.points[3]), 275 avg(this.points[3], this.points[0])]; 276 277 return points; 278 } 279 280 this.drawDragPoint = function(camera, index, position, localSpace, alpha) 281 { 282 if (alpha == undefined) 283 alpha = 1; 284 285 if (index<4) 286 { 287 camera.drawRectangle(this.points[index], camera.invScale(10), "rgba(255,0,0," + alpha + ")", 2); 288 } 289 else 290 { 291 var index0 = index-4; 292 var index1 = (index0+1) % 4; 293 294 var a = avg(this.points[index0], this.points[index1]); 295 var dir = sub(this.points[index1], this.points[index0]).unit().neg(); 296 var tan = transpose(dir); 297 298 var b = add(a, mul(tan, camera.invScale(30))); 299 300 camera.drawArrow(a, b, 8, "rgba(255,0,0," + alpha + ")", 3); 301 } 302 } 303 304 this.setDragPointPos = function(index, p, localSpace, dragStartPoint, camera) 305 { 306 var points = [ this.points[0], 307 this.points[1], 308 this.points[2], 309 this.points[3], 310 avg(this.points[0], this.points[1]), 311 avg(this.points[1], this.points[2]), 312 avg(this.points[2], this.points[3]), 313 avg(this.points[3], this.points[0])]; 314 315 if (index < 4) 316 { 317 if (localSpace) 318 { 319 var center = avg(this.points[0], this.points[2]); 320 var halfSize = abs(sub(p, center)); 321 322 this.points[0] = sub(center, halfSize); 323 this.points[2] = add(center, halfSize); 324 this.points[1].x = this.points[2].x; 325 this.points[1].y = this.points[0].y; 326 this.points[3].x = this.points[0].x; 327 this.points[3].y = this.points[2].y; 328 } 329 else 330 { 331 this.points[index] = p; 332 333 if (index==0) 334 { 335 this.points[3].x = p.x; 336 this.points[1].y = p.y; 337 } 338 else if (index==1) 339 { 340 this.points[2].x = p.x; 341 this.points[0].y = p.y; 342 } 343 else if (index==2) 344 { 345 this.points[1].x = p.x; 346 this.points[3].y = p.y; 347 } 348 else if (index==3) 349 { 350 this.points[0].x = p.x; 351 this.points[2].y = p.y; 352 } 353 } 354 } 355 else if (index < 8) 356 { 357 if (index==4) 358 { 359 this.points[0].y = p.y; 360 this.points[1].y = p.y; 361 } 362 else if (index==5) 363 { 364 this.points[1].x = p.x; 365 this.points[2].x = p.x; 366 } 367 else if (index==6) 368 { 369 this.points[2].y = p.y; 370 this.points[3].y = p.y; 371 } 372 else if (index==7) 373 { 374 this.points[0].x = p.x; 375 this.points[3].x = p.x; 376 } 377 } 378 else 379 { } 380 381 if (camera != undefined) 382 { 383 var p0 = this.points[0].copy(); 384 var p1 = this.points[2].copy(); 385 386 var delta = sub(p1, p0); 387 388 var p = p1.copy();
389 p.x += ((p1.x < p0.x) ? +1 : -1) * camera.invScale(10); 390 p.y += camera.invScale(10); 391 392 camera.drawText(p, "dx: " + delta.x.toFixed(1) + " dy: " + delta.y.toFixed(1), "#000000", (p1.x < p0.x) ? "left" : "right", 0, "12px Arial"); 393 } 394 395 this.onChange(); 396 } 397 398 this.getOrigin = function() 399 { 400 return this.points[0]; 401 } 402 403 this.setOrigin = function(p) 404 { 405 var delta = sub(p, this.points[0]); 406 407 for (var i = 0; i != 4; ++i) 408 { 409 this.points[i] = add(this.points[i], delta); 410 } 411 412 this.onChange(); 413 } 414 415 this.getProperties = function() 416 { 417 var appearanceControl = new PopoutContainer(undefined, "images/color_wheel.svg"); 418 { 419 appearanceControl.addControl("", new AppearanceControl(this.appearance, true, true, function(){ this.onChange(); }.bind(this)) ); 420 } 421 422 return [ 423 {name: "Appearance", control:appearanceControl }, 424 {name: "Rows", control: new PopoutSlider(1, 16, this.rows, 1, function (value) { this.rows = value; this.onChange(); }.bind(this)) }, 425 {name: "Columns", control: new PopoutSlider(1, 16, this.columns, 1, function (value) { this.columns = value; this.onChange(); }.bind(this)) }, 426 {name: "Center Points", control: new TickBox(this.centerPoints, function (value) { this.centerPoints = value; this.onChange(); }.bind(this)) } 427 ]; 428 } 429 430 this.toggleVisibility = function(v) 431 { 432 var newVisible = (v!==undefined) ? v : !this.visible; 433 if (this.visible != newVisible) 434 { 435 this.visible = newVisible; 436 this.onChange(); 437 } 438 } 439 440 this.isVisible = function() 441 { 442 return this.visible; 443 } 444 445 this.toggleFrozen = function(f) 446 { 447 this.frozen = (f!==undefined) ? f : !this.frozen; 448 this.onChange(); 449 } 450 451 this.isFrozen = function() 452 { 453 return this.frozen; 454 } 455 456 this.setSelected = function(selected) 457 { 458 this.selected = selected; 459 } 460 461 this.isSelected = function() 462 { 463 return this.selected; 464 } 465 466 this.onChange(); 467}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.