|
31 | 31 | ppe: 3,
|
32 | 32 | maxForce: 10,
|
33 | 33 | iterations: 0,
|
| 34 | + converged: false, |
34 | 35 | settings: {
|
35 | 36 | linLogMode: false,
|
36 | 37 | outboundAttractionDistribution: false,
|
|
40 | 41 | strongGravityMode: false,
|
41 | 42 | gravity: 1,
|
42 | 43 | barnesHutOptimize: false,
|
| 44 | + |
| 45 | + // Are those settings |
43 | 46 | barnesHutTheta: 1.2,
|
44 | 47 | outboundAttCompensation: 1,
|
45 | 48 | totalSwinging: 0,
|
46 | 49 | totalEffectiveTraction: 0,
|
47 | 50 | speedEfficiency: 1,
|
48 |
| - complexIntervals: 500, |
49 |
| - simpleIntervals: 1000, |
50 |
| - converged: false |
51 | 51 | }
|
52 | 52 | };
|
53 | 53 |
|
|
206 | 206 |
|
207 | 207 | // MATH: get distances stuff and power 2 issues
|
208 | 208 | function pass() {
|
209 |
| - var n, n1, n2, e, s, t, w; |
| 209 | + var n, n1, n2, e, w, g; |
210 | 210 |
|
211 | 211 | var rootRegion,
|
212 | 212 | outboundAttCompensation,
|
| 213 | + coefficient, |
213 | 214 | xDist,
|
214 | 215 | yDist,
|
| 216 | + ewc, |
215 | 217 | distance,
|
216 | 218 | factor;
|
217 | 219 |
|
|
236 | 238 | // If outbound attraction distribution, compensate
|
237 | 239 | if (W.settings.outboundAttractionDistribution) {
|
238 | 240 | outboundAttCompensation = 0;
|
239 |
| - for (n = 0, l = W.nodes.length; n < l; n++) { |
| 241 | + for (n = 0; n < W.nodesLength; n += W.ppn) { |
240 | 242 | outboundAttCompensation += W.nodeMatrix[np(n, 'mass')];
|
241 | 243 | }
|
242 | 244 |
|
243 |
| - outboundAttCompensation /= l; |
| 245 | + outboundAttCompensation /= W.nodesLength; |
244 | 246 | }
|
245 | 247 |
|
246 | 248 |
|
|
291 | 293 | W.nodeMatrix[np(n1, 'dx')] += xDist * factor;
|
292 | 294 | W.nodeMatrix[np(n1, 'dy')] += yDist * factor;
|
293 | 295 |
|
294 |
| - W.nodeMatrix[np(n2, 'dx')] += xDist * factor; |
295 |
| - W.nodeMatrix[np(n2, 'dy')] += yDist * factor; |
| 296 | + W.nodeMatrix[np(n2, 'dx')] -= xDist * factor; |
| 297 | + W.nodeMatrix[np(n2, 'dy')] -= yDist * factor; |
296 | 298 | }
|
297 | 299 | }
|
298 | 300 | else {
|
|
310 | 312 | W.nodeMatrix[np(n1, 'dx')] += xDist * factor;
|
311 | 313 | W.nodeMatrix[np(n1, 'dy')] += yDist * factor;
|
312 | 314 |
|
313 |
| - W.nodeMatrix[np(n2, 'dx')] += xDist * factor; |
314 |
| - W.nodeMatrix[np(n2, 'dy')] += yDist * factor; |
| 315 | + W.nodeMatrix[np(n2, 'dx')] -= xDist * factor; |
| 316 | + W.nodeMatrix[np(n2, 'dy')] -= yDist * factor; |
315 | 317 | }
|
316 | 318 | }
|
317 | 319 | }
|
|
321 | 323 |
|
322 | 324 | // 3) Gravity
|
323 | 325 | //------------
|
| 326 | + g = W.settings.gravity / W.settings.scalingRatio; |
| 327 | + coefficient = W.settings.scalingRatio; |
324 | 328 | for (n = 0; n < W.nodesLength; n += W.ppn) {
|
325 | 329 |
|
326 |
| - // TODO: apply gravity |
| 330 | + // Common to both methods |
| 331 | + xDist = W.nodeMatrix[np(n, 'x')]; |
| 332 | + yDist = W.nodeMatrix[np(n, 'y')]; |
| 333 | + distance = Math.sqrt( |
| 334 | + Math.pow(xDist, 2) + Math.pow(yDist, 2) |
| 335 | + ); |
| 336 | + |
| 337 | + if (W.settings.strongGravityMode) { |
| 338 | + |
| 339 | + //-- Strong gravity |
| 340 | + if (distance > 0) |
| 341 | + factor = coefficient * W.nodeMatrix[np(n, 'mass')] * g; |
| 342 | + } |
| 343 | + else { |
| 344 | + |
| 345 | + //-- Linear Anti-collision Repulsion n |
| 346 | + if (distance > 0) |
| 347 | + factor = coefficient * W.nodeMatrix[np(n, 'mass')] * g / distance; |
| 348 | + } |
327 | 349 | }
|
328 | 350 |
|
| 351 | + // Updating node's dx and dy |
| 352 | + W.nodeMatrix[np(n, 'dx')] -= xDist * factor; |
| 353 | + W.nodeMatrix[np(n, 'dy')] -= yDist * factor; |
| 354 | + |
329 | 355 |
|
330 | 356 | // 4) Attraction
|
331 | 357 | //---------------
|
| 358 | + coefficient = 1 * |
| 359 | + (W.settings.outboundAttractionDistribution ? |
| 360 | + outboundAttCompensation : |
| 361 | + 1); |
| 362 | + |
| 363 | + // TODO: simplify distance |
| 364 | + // TODO: coefficient is always used as -c --> optimize? |
332 | 365 | for (e = 0; e < W.edgesLength; e += W.ppe) {
|
333 |
| - s = W.edgeMatrix[ep(e, 'source')]; |
334 |
| - t = W.edgeMatrix[ep(e, 'target')]; |
| 366 | + n1 = W.edgeMatrix[ep(e, 'source')]; |
| 367 | + n2 = W.edgeMatrix[ep(e, 'target')]; |
335 | 368 | w = W.edgeMatrix[ep(e, 'weight')];
|
336 | 369 |
|
337 |
| - // TODO: apply attraction |
| 370 | + // Edge weight influence |
| 371 | + if (W.settings.edgeWeightInfluence === 0) |
| 372 | + ewc = 1 |
| 373 | + else if (W.settings.edgeWeightInfluence === 1) |
| 374 | + ewc = w; |
| 375 | + else |
| 376 | + ewc = Math.pow(w, W.settings.edgeWeightInfluence); |
| 377 | + |
| 378 | + // Common measures |
| 379 | + xDist = W.nodeMatrix[np(n1, 'x')] - W.nodeMatrix[np(n2, 'x')]; |
| 380 | + yDist = W.nodeMatrix[np(n1, 'y')] - W.nodeMatrix[np(n2, 'y')]; |
| 381 | + |
| 382 | + // Applying attraction to nodes |
| 383 | + if (W.settings.adjustSizes) { |
| 384 | + if (W.settings.linLogMode) { |
| 385 | + if (W.settings.outboundAttractionDistribution) { |
| 386 | + |
| 387 | + //-- LinLog Degree Distributed Anti-collision Attraction |
| 388 | + distance = Math.sqrt( |
| 389 | + (Math.pow(xDist, 2) + Math.pow(yDist, 2)) - |
| 390 | + W.nodeMatrix[np(n1, 'size')] - |
| 391 | + W.nodeMatrix[np(n2, 'size')] |
| 392 | + ); |
| 393 | + |
| 394 | + if (distance > 0) { |
| 395 | + factor = -coefficient * ewc * Math.log(1 + distance) / |
| 396 | + distance / |
| 397 | + W.nodeMatrix[np(n1, 'mass')]; |
| 398 | + } |
| 399 | + } |
| 400 | + else { |
| 401 | + |
| 402 | + //-- LinLog Anti-collision Attraction |
| 403 | + distance = Math.sqrt( |
| 404 | + (Math.pow(xDist, 2) + Math.pow(yDist, 2)) - |
| 405 | + W.nodeMatrix[np(n1, 'size')] - |
| 406 | + W.nodeMatrix[np(n2, 'size')] |
| 407 | + ); |
| 408 | + |
| 409 | + if (distance > 0) { |
| 410 | + factor = -coefficient * ewc * Math.log(1 + distance) / distance; |
| 411 | + } |
| 412 | + } |
| 413 | + } |
| 414 | + else { |
| 415 | + if (W.settings.outboundAttractionDistribution) { |
| 416 | + |
| 417 | + //-- Linear Degree Distributed Anti-collision Attraction |
| 418 | + distance = Math.sqrt( |
| 419 | + (Math.pow(xDist, 2) + Math.pow(yDist, 2)) - |
| 420 | + W.nodeMatrix[np(n1, 'size')] - |
| 421 | + W.nodeMatrix[np(n2, 'size')] |
| 422 | + ); |
| 423 | + |
| 424 | + if (distance > 0) { |
| 425 | + factor = -coefficient * ewc / W.nodeMatrix[np(n1, 'mass')]; |
| 426 | + } |
| 427 | + } |
| 428 | + else { |
| 429 | + |
| 430 | + //-- Linear Anti-collision Attraction |
| 431 | + distance = Math.sqrt( |
| 432 | + (Math.pow(xDist, 2) + Math.pow(yDist, 2)) - |
| 433 | + W.nodeMatrix[np(n1, 'size')] - |
| 434 | + W.nodeMatrix[np(n2, 'size')] |
| 435 | + ); |
| 436 | + |
| 437 | + if (distance > 0) { |
| 438 | + factor = -coefficient * ewc; |
| 439 | + } |
| 440 | + } |
| 441 | + } |
| 442 | + } |
| 443 | + else { |
| 444 | + if (W.settings.linLogMode) { |
| 445 | + if (W.settings.outboundAttractionDistribution) { |
| 446 | + |
| 447 | + //-- LinLog Degree Distributed Attraction |
| 448 | + distance = Math.sqrt( |
| 449 | + Math.pow(xDist, 2) + Math.pow(yDist, 2) |
| 450 | + ); |
| 451 | + |
| 452 | + if (distance > 0) { |
| 453 | + factor = -coefficient * ewc * Math.log(1 + distance) / |
| 454 | + distance / |
| 455 | + W.nodeMatrix[np(n1, 'mass')]; |
| 456 | + } |
| 457 | + } |
| 458 | + else { |
| 459 | + |
| 460 | + //-- LinLog Attraction |
| 461 | + distance = Math.sqrt( |
| 462 | + Math.pow(xDist, 2) + Math.pow(yDist, 2) |
| 463 | + ); |
| 464 | + |
| 465 | + if (distance > 0) |
| 466 | + factor = -coefficient * ewc * Math.log(1 + distance) / distance; |
| 467 | + } |
| 468 | + } |
| 469 | + else { |
| 470 | + if (W.settings.outboundAttractionDistribution) { |
| 471 | + |
| 472 | + //-- Linear Attraction Mass Distributed |
| 473 | + // NOTE: Distance is set to 1 to override condition |
| 474 | + distance = 1; |
| 475 | + factor = -coefficient * ewc / W.nodeMatrix[np(n1, 'mass')]; |
| 476 | + } |
| 477 | + else { |
| 478 | + |
| 479 | + //-- Linear Attraction |
| 480 | + // NOTE: Distance is set to 1 to override condition |
| 481 | + distance = 1; |
| 482 | + factor = -coefficient * ewc; |
| 483 | + } |
| 484 | + } |
| 485 | + } |
| 486 | + |
| 487 | + // Updating nodes' dx and dy |
| 488 | + // TODO: if condition or factor = 1? |
| 489 | + if (distance > 0) { |
| 490 | + |
| 491 | + // Updating nodes' dx and dy |
| 492 | + W.nodeMatrix[np(n1, 'dx')] += xDist * factor; |
| 493 | + W.nodeMatrix[np(n1, 'dy')] += yDist * factor; |
| 494 | + |
| 495 | + W.nodeMatrix[np(n2, 'dx')] -= xDist * factor; |
| 496 | + W.nodeMatrix[np(n2, 'dy')] -= yDist * factor; |
| 497 | + } |
338 | 498 | }
|
339 | 499 |
|
| 500 | + |
340 | 501 | // 5) Apply Forces
|
341 | 502 | //-----------------
|
342 | 503 | var force,
|
|
0 commit comments