curvetween2.pde 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. private PVector ballPos;
  2. private PVector ballStart;
  3. private PVector ballTarget;
  4. private PVector ballDelta;
  5. private PVector controlPoint;
  6. private PVector controlPointFlux;
  7. private PVector leftFloater;
  8. private PVector rightFloater;
  9. private PVector leftDelta;
  10. private PVector rightDelta;
  11. private PVector center;
  12. private float slope;
  13. private float clock;
  14. private float elapsed;
  15. private float duration;
  16. private boolean debugLines;
  17. public void setup() {
  18. debugLines = false;
  19. size(800, 600);
  20. ballPos = new PVector(50, 50);
  21. ballStart = new PVector();
  22. ballTarget = new PVector();
  23. ballDelta = new PVector();
  24. controlPointFlux = new PVector();
  25. controlPoint = new PVector();
  26. leftFloater = new PVector();
  27. rightFloater = new PVector();
  28. leftDelta = new PVector();
  29. rightDelta = new PVector();
  30. center = new PVector();
  31. clock = millis();
  32. duration = 5000;
  33. reset(750, 550);
  34. }
  35. private void reset(float x, float y) {
  36. ballStart.x = ballPos.x;
  37. ballStart.y = ballPos.y;
  38. ballTarget.x = x;
  39. ballTarget.y = y;
  40. ballDelta.x = ballTarget.x - ballStart.x;
  41. ballDelta.y = ballTarget.y - ballStart.y;
  42. controlPointFlux.x = ballDelta.x / 2;
  43. controlPointFlux.y = ballDelta.y / 2;
  44. controlPoint.x = ballStart.x + ballDelta.x / 2 + controlPointFlux.x;
  45. controlPoint.y = ballStart.y + ballDelta.y / 2 - controlPointFlux.y;
  46. leftFloater.x = ballStart.x;
  47. leftFloater.y = ballStart.y;
  48. leftDelta.x = controlPoint.x - leftFloater.x;
  49. leftDelta.y = controlPoint.y - leftFloater.y;
  50. rightFloater.x = controlPoint.x;
  51. rightFloater.y = controlPoint.y;
  52. rightDelta.x = ballTarget.x - controlPoint.x;
  53. rightDelta.y = ballTarget.y - controlPoint.y;
  54. elapsed = 0;
  55. }
  56. private void update() {
  57. if (mousePressed) {
  58. clock = millis();
  59. reset(mouseX, mouseY);
  60. return;
  61. }
  62. if (elapsed >= duration) {
  63. ballPos.x = ballTarget.x;
  64. ballPos.y = ballTarget.y;
  65. return;
  66. }
  67. float newClock = millis();
  68. float delta = newClock - clock;
  69. elapsed += delta;
  70. clock = newClock;
  71. float easeAmount = easeInOut(elapsed / duration);
  72. leftFloater.x = ballStart.x + leftDelta.x * easeAmount;
  73. leftFloater.y = ballStart.y + leftDelta.y * easeAmount;
  74. rightFloater.x = controlPoint.x + rightDelta.x * easeAmount;
  75. rightFloater.y = controlPoint.y + rightDelta.y * easeAmount;
  76. center.x = (leftFloater.x + rightFloater.x) / 2;
  77. center.y = (leftFloater.y + rightFloater.y) / 2;
  78. slope = (rightFloater.y - leftFloater.y / rightFloater.x - leftFloater.x);
  79. ballPos.x = leftFloater.x + (rightFloater.x - leftFloater.x) * easeAmount;
  80. ballPos.y = leftFloater.y + (rightFloater.y - leftFloater.y) * easeAmount;
  81. }
  82. public void draw() {
  83. update();
  84. background(0, 0, 0);
  85. fill(255, 255, 255);
  86. noStroke();
  87. ellipse(ballPos.x, ballPos.y, 20, 20);
  88. if (debugLines) {
  89. //points
  90. fill(0, 0, 0, 0);
  91. stroke(255, 0, 0);
  92. line(leftFloater.x, leftFloater.y, rightFloater.x, rightFloater.y);
  93. stroke(255, 255, 255);
  94. ellipse(center.x, center.y, 10, 10);
  95. stroke(255, 0, 0);
  96. ellipse(leftFloater.x, leftFloater.y, 10, 10);
  97. ellipse(rightFloater.x, rightFloater.y, 10, 10);
  98. stroke(0, 255, 0);
  99. line(ballStart.x, ballStart.y, controlPoint.x, controlPoint.y);
  100. line(controlPoint.x, controlPoint.y, ballTarget.x, ballTarget.y);
  101. ellipse(ballStart.x, ballStart.y, 10, 10);
  102. ellipse(ballTarget.x, ballTarget.y, 10, 10);
  103. ellipse(controlPoint.x, controlPoint.y, 10, 10);
  104. }
  105. }
  106. private float linear(float k) {
  107. return k;
  108. }
  109. private float easeOut(float k) {
  110. return -k * (k-2);
  111. }
  112. private float easeInOut(float k) {
  113. if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
  114. return - 0.5 * ( --k * ( k - 2 ) - 1 );
  115. }
  116. void keyPressed() {
  117. if (key == 'd') {
  118. debugLines = !debugLines;
  119. }
  120. }