vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
3.9 KiB

  1. var Point3d = require('./Point3d');
  2. /**
  3. * @class Camera
  4. * The camera is mounted on a (virtual) camera arm. The camera arm can rotate
  5. * The camera is always looking in the direction of the origin of the arm.
  6. * This way, the camera always rotates around one fixed point, the location
  7. * of the camera arm.
  8. *
  9. * Documentation:
  10. * http://en.wikipedia.org/wiki/3D_projection
  11. */
  12. Camera = function () {
  13. this.armLocation = new Point3d();
  14. this.armRotation = {};
  15. this.armRotation.horizontal = 0;
  16. this.armRotation.vertical = 0;
  17. this.armLength = 1.7;
  18. this.cameraLocation = new Point3d();
  19. this.cameraRotation = new Point3d(0.5*Math.PI, 0, 0);
  20. this.calculateCameraOrientation();
  21. };
  22. /**
  23. * Set the location (origin) of the arm
  24. * @param {Number} x Normalized value of x
  25. * @param {Number} y Normalized value of y
  26. * @param {Number} z Normalized value of z
  27. */
  28. Camera.prototype.setArmLocation = function(x, y, z) {
  29. this.armLocation.x = x;
  30. this.armLocation.y = y;
  31. this.armLocation.z = z;
  32. this.calculateCameraOrientation();
  33. };
  34. /**
  35. * Set the rotation of the camera arm
  36. * @param {Number} horizontal The horizontal rotation, between 0 and 2*PI.
  37. * Optional, can be left undefined.
  38. * @param {Number} vertical The vertical rotation, between 0 and 0.5*PI
  39. * if vertical=0.5*PI, the graph is shown from the
  40. * top. Optional, can be left undefined.
  41. */
  42. Camera.prototype.setArmRotation = function(horizontal, vertical) {
  43. if (horizontal !== undefined) {
  44. this.armRotation.horizontal = horizontal;
  45. }
  46. if (vertical !== undefined) {
  47. this.armRotation.vertical = vertical;
  48. if (this.armRotation.vertical < 0) this.armRotation.vertical = 0;
  49. if (this.armRotation.vertical > 0.5*Math.PI) this.armRotation.vertical = 0.5*Math.PI;
  50. }
  51. if (horizontal !== undefined || vertical !== undefined) {
  52. this.calculateCameraOrientation();
  53. }
  54. };
  55. /**
  56. * Retrieve the current arm rotation
  57. * @return {object} An object with parameters horizontal and vertical
  58. */
  59. Camera.prototype.getArmRotation = function() {
  60. var rot = {};
  61. rot.horizontal = this.armRotation.horizontal;
  62. rot.vertical = this.armRotation.vertical;
  63. return rot;
  64. };
  65. /**
  66. * Set the (normalized) length of the camera arm.
  67. * @param {Number} length A length between 0.71 and 5.0
  68. */
  69. Camera.prototype.setArmLength = function(length) {
  70. if (length === undefined)
  71. return;
  72. this.armLength = length;
  73. // Radius must be larger than the corner of the graph,
  74. // which has a distance of sqrt(0.5^2+0.5^2) = 0.71 from the center of the
  75. // graph
  76. if (this.armLength < 0.71) this.armLength = 0.71;
  77. if (this.armLength > 5.0) this.armLength = 5.0;
  78. this.calculateCameraOrientation();
  79. };
  80. /**
  81. * Retrieve the arm length
  82. * @return {Number} length
  83. */
  84. Camera.prototype.getArmLength = function() {
  85. return this.armLength;
  86. };
  87. /**
  88. * Retrieve the camera location
  89. * @return {Point3d} cameraLocation
  90. */
  91. Camera.prototype.getCameraLocation = function() {
  92. return this.cameraLocation;
  93. };
  94. /**
  95. * Retrieve the camera rotation
  96. * @return {Point3d} cameraRotation
  97. */
  98. Camera.prototype.getCameraRotation = function() {
  99. return this.cameraRotation;
  100. };
  101. /**
  102. * Calculate the location and rotation of the camera based on the
  103. * position and orientation of the camera arm
  104. */
  105. Camera.prototype.calculateCameraOrientation = function() {
  106. // calculate location of the camera
  107. this.cameraLocation.x = this.armLocation.x - this.armLength * Math.sin(this.armRotation.horizontal) * Math.cos(this.armRotation.vertical);
  108. this.cameraLocation.y = this.armLocation.y - this.armLength * Math.cos(this.armRotation.horizontal) * Math.cos(this.armRotation.vertical);
  109. this.cameraLocation.z = this.armLocation.z + this.armLength * Math.sin(this.armRotation.vertical);
  110. // calculate rotation of the camera
  111. this.cameraRotation.x = Math.PI/2 - this.armRotation.vertical;
  112. this.cameraRotation.y = 0;
  113. this.cameraRotation.z = -this.armRotation.horizontal;
  114. };
  115. module.exports = Camera;