diff --git a/src/data/examples/en/13_Motion/07_Circle_Collision.js b/src/data/examples/en/13_Motion/07_Circle_Collision.js
new file mode 100644
index 0000000000..876bc23d6e
--- /dev/null
+++ b/src/data/examples/en/13_Motion/07_Circle_Collision.js
@@ -0,0 +1,145 @@
+/*
+ * @name Circle Collision
+ * @frame 710,400 (optional)
+ * @description This is a port of the "Circle Collision" example from processing.org/examples
This example uses vectors for better visualization of physical Quantity
+ */
+class Ball {
+ constructor(x, y, r) {
+ this.position = new p5.Vector(x, y);
+ this.velocity = p5.Vector.random2D();
+ this.velocity.mult(3);
+ this.r = r;
+ this.m = r * 0.1;
+ }
+ update() {
+ this.position.add(this.velocity);
+ }
+
+ checkBoundaryCollision() {
+ if (this.position.x > width - this.r) {
+ this.position.x = width - this.r;
+ this.velocity.x *= -1;
+ } else if (this.position.x < this.r) {
+ this.position.x = this.r;
+ this.velocity.x *= -1;
+ } else if (this.position.y > height - this.r) {
+ this.position.y = height - this.r;
+ this.velocity.y *= -1;
+ } else if (this.position.y < this.r) {
+ this.position.y = this.r;
+ this.velocity.y *= -1;
+ }
+ }
+
+ checkCollision(other) {
+ // Get distances between the balls components
+ let distanceVect = p5.Vector.sub(other.position, this.position);
+
+ // Calculate magnitude of the vector separating the balls
+ let distanceVectMag = distanceVect.mag();
+
+ // Minimum distance before they are touching
+ let minDistance = this.r + other.r;
+
+ if (distanceVectMag < minDistance) {
+ let distanceCorrection = (minDistance - distanceVectMag) / 2.0;
+ let d = distanceVect.copy();
+ let correctionVector = d.normalize().mult(distanceCorrection);
+ other.position.add(correctionVector);
+ this.position.sub(correctionVector);
+
+ // get angle of distanceVect
+ let theta = distanceVect.heading();
+ // precalculate trig values
+ let sine = sin(theta);
+ let cosine = cos(theta);
+
+ /* bTemp will hold rotated ball this.positions. You
+ just need to worry about bTemp[1] this.position*/
+ let bTemp = [new p5.Vector(), new p5.Vector()];
+
+ /* this ball's this.position is relative to the other
+ so you can use the vector between them (bVect) as the
+ reference point in the rotation expressions.
+ bTemp[0].this.position.x and bTemp[0].this.position.y will initialize
+ automatically to 0.0, which is what you want
+ since b[1] will rotate around b[0] */
+ bTemp[1].x = cosine * distanceVect.x + sine * distanceVect.y;
+ bTemp[1].y = cosine * distanceVect.y - sine * distanceVect.x;
+
+ // rotate Temporary velocities
+ let vTemp = [new p5.Vector(), new p5.Vector()];
+
+ vTemp[0].x = cosine * this.velocity.x + sine * this.velocity.y;
+ vTemp[0].y = cosine * this.velocity.y - sine * this.velocity.x;
+ vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y;
+ vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x;
+
+ /* Now that velocities are rotated, you can use 1D
+ conservation of momentum equations to calculate
+ the final this.velocity along the x-axis. */
+ let vFinal = [new p5.Vector(), new p5.Vector()];
+
+ // final rotated this.velocity for b[0]
+ vFinal[0].x =
+ ((this.m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) /
+ (this.m + other.m);
+ vFinal[0].y = vTemp[0].y;
+
+ // final rotated this.velocity for b[0]
+ vFinal[1].x =
+ ((other.m - this.m) * vTemp[1].x + 2 * this.m * vTemp[0].x) /
+ (this.m + other.m);
+ vFinal[1].y = vTemp[1].y;
+
+ // hack to avoid clumping
+ bTemp[0].x += vFinal[0].x;
+ bTemp[1].x += vFinal[1].x;
+
+ /* Rotate ball this.positions and velocities back
+ Reverse signs in trig expressions to rotate
+ in the opposite direction */
+ // rotate balls
+ let bFinal = [new p5.Vector(), new p5.Vector()];
+
+ bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
+ bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
+ bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
+ bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
+
+ // update balls to screen this.position
+ other.position.x = this.position.x + bFinal[1].x;
+ other.position.y = this.position.y + bFinal[1].y;
+
+ this.position.add(bFinal[0]);
+
+ // update velocities
+ this.velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
+ this.velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
+ other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y;
+ other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x;
+ }
+ }
+
+ display() {
+ noStroke();
+ fill(204);
+ ellipse(this.position.x, this.position.y, this.r * 2, this.r * 2);
+ }
+}
+let balls = [new Ball(100, 400, 20), new Ball(700, 400, 80)];
+console.log(balls);
+function setup() {
+ createCanvas(710, 400);
+}
+
+function draw() {
+ background(51);
+ for (let i = 0; i < balls.length; i++) {
+ let b = balls[i];
+ b.update();
+ b.display();
+ b.checkBoundaryCollision();
+ balls[0].checkCollision(balls[1]);
+ }
+}
diff --git a/src/data/examples/es/13_Motion/07_Circle_Collision.js b/src/data/examples/es/13_Motion/07_Circle_Collision.js
new file mode 100644
index 0000000000..876bc23d6e
--- /dev/null
+++ b/src/data/examples/es/13_Motion/07_Circle_Collision.js
@@ -0,0 +1,145 @@
+/*
+ * @name Circle Collision
+ * @frame 710,400 (optional)
+ * @description This is a port of the "Circle Collision" example from processing.org/examples
This example uses vectors for better visualization of physical Quantity
+ */
+class Ball {
+ constructor(x, y, r) {
+ this.position = new p5.Vector(x, y);
+ this.velocity = p5.Vector.random2D();
+ this.velocity.mult(3);
+ this.r = r;
+ this.m = r * 0.1;
+ }
+ update() {
+ this.position.add(this.velocity);
+ }
+
+ checkBoundaryCollision() {
+ if (this.position.x > width - this.r) {
+ this.position.x = width - this.r;
+ this.velocity.x *= -1;
+ } else if (this.position.x < this.r) {
+ this.position.x = this.r;
+ this.velocity.x *= -1;
+ } else if (this.position.y > height - this.r) {
+ this.position.y = height - this.r;
+ this.velocity.y *= -1;
+ } else if (this.position.y < this.r) {
+ this.position.y = this.r;
+ this.velocity.y *= -1;
+ }
+ }
+
+ checkCollision(other) {
+ // Get distances between the balls components
+ let distanceVect = p5.Vector.sub(other.position, this.position);
+
+ // Calculate magnitude of the vector separating the balls
+ let distanceVectMag = distanceVect.mag();
+
+ // Minimum distance before they are touching
+ let minDistance = this.r + other.r;
+
+ if (distanceVectMag < minDistance) {
+ let distanceCorrection = (minDistance - distanceVectMag) / 2.0;
+ let d = distanceVect.copy();
+ let correctionVector = d.normalize().mult(distanceCorrection);
+ other.position.add(correctionVector);
+ this.position.sub(correctionVector);
+
+ // get angle of distanceVect
+ let theta = distanceVect.heading();
+ // precalculate trig values
+ let sine = sin(theta);
+ let cosine = cos(theta);
+
+ /* bTemp will hold rotated ball this.positions. You
+ just need to worry about bTemp[1] this.position*/
+ let bTemp = [new p5.Vector(), new p5.Vector()];
+
+ /* this ball's this.position is relative to the other
+ so you can use the vector between them (bVect) as the
+ reference point in the rotation expressions.
+ bTemp[0].this.position.x and bTemp[0].this.position.y will initialize
+ automatically to 0.0, which is what you want
+ since b[1] will rotate around b[0] */
+ bTemp[1].x = cosine * distanceVect.x + sine * distanceVect.y;
+ bTemp[1].y = cosine * distanceVect.y - sine * distanceVect.x;
+
+ // rotate Temporary velocities
+ let vTemp = [new p5.Vector(), new p5.Vector()];
+
+ vTemp[0].x = cosine * this.velocity.x + sine * this.velocity.y;
+ vTemp[0].y = cosine * this.velocity.y - sine * this.velocity.x;
+ vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y;
+ vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x;
+
+ /* Now that velocities are rotated, you can use 1D
+ conservation of momentum equations to calculate
+ the final this.velocity along the x-axis. */
+ let vFinal = [new p5.Vector(), new p5.Vector()];
+
+ // final rotated this.velocity for b[0]
+ vFinal[0].x =
+ ((this.m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) /
+ (this.m + other.m);
+ vFinal[0].y = vTemp[0].y;
+
+ // final rotated this.velocity for b[0]
+ vFinal[1].x =
+ ((other.m - this.m) * vTemp[1].x + 2 * this.m * vTemp[0].x) /
+ (this.m + other.m);
+ vFinal[1].y = vTemp[1].y;
+
+ // hack to avoid clumping
+ bTemp[0].x += vFinal[0].x;
+ bTemp[1].x += vFinal[1].x;
+
+ /* Rotate ball this.positions and velocities back
+ Reverse signs in trig expressions to rotate
+ in the opposite direction */
+ // rotate balls
+ let bFinal = [new p5.Vector(), new p5.Vector()];
+
+ bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
+ bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
+ bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
+ bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
+
+ // update balls to screen this.position
+ other.position.x = this.position.x + bFinal[1].x;
+ other.position.y = this.position.y + bFinal[1].y;
+
+ this.position.add(bFinal[0]);
+
+ // update velocities
+ this.velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
+ this.velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
+ other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y;
+ other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x;
+ }
+ }
+
+ display() {
+ noStroke();
+ fill(204);
+ ellipse(this.position.x, this.position.y, this.r * 2, this.r * 2);
+ }
+}
+let balls = [new Ball(100, 400, 20), new Ball(700, 400, 80)];
+console.log(balls);
+function setup() {
+ createCanvas(710, 400);
+}
+
+function draw() {
+ background(51);
+ for (let i = 0; i < balls.length; i++) {
+ let b = balls[i];
+ b.update();
+ b.display();
+ b.checkBoundaryCollision();
+ balls[0].checkCollision(balls[1]);
+ }
+}
diff --git a/src/data/examples/ko/13_Motion/07_Circle_Collision.js b/src/data/examples/ko/13_Motion/07_Circle_Collision.js
new file mode 100644
index 0000000000..876bc23d6e
--- /dev/null
+++ b/src/data/examples/ko/13_Motion/07_Circle_Collision.js
@@ -0,0 +1,145 @@
+/*
+ * @name Circle Collision
+ * @frame 710,400 (optional)
+ * @description This is a port of the "Circle Collision" example from processing.org/examples
This example uses vectors for better visualization of physical Quantity
+ */
+class Ball {
+ constructor(x, y, r) {
+ this.position = new p5.Vector(x, y);
+ this.velocity = p5.Vector.random2D();
+ this.velocity.mult(3);
+ this.r = r;
+ this.m = r * 0.1;
+ }
+ update() {
+ this.position.add(this.velocity);
+ }
+
+ checkBoundaryCollision() {
+ if (this.position.x > width - this.r) {
+ this.position.x = width - this.r;
+ this.velocity.x *= -1;
+ } else if (this.position.x < this.r) {
+ this.position.x = this.r;
+ this.velocity.x *= -1;
+ } else if (this.position.y > height - this.r) {
+ this.position.y = height - this.r;
+ this.velocity.y *= -1;
+ } else if (this.position.y < this.r) {
+ this.position.y = this.r;
+ this.velocity.y *= -1;
+ }
+ }
+
+ checkCollision(other) {
+ // Get distances between the balls components
+ let distanceVect = p5.Vector.sub(other.position, this.position);
+
+ // Calculate magnitude of the vector separating the balls
+ let distanceVectMag = distanceVect.mag();
+
+ // Minimum distance before they are touching
+ let minDistance = this.r + other.r;
+
+ if (distanceVectMag < minDistance) {
+ let distanceCorrection = (minDistance - distanceVectMag) / 2.0;
+ let d = distanceVect.copy();
+ let correctionVector = d.normalize().mult(distanceCorrection);
+ other.position.add(correctionVector);
+ this.position.sub(correctionVector);
+
+ // get angle of distanceVect
+ let theta = distanceVect.heading();
+ // precalculate trig values
+ let sine = sin(theta);
+ let cosine = cos(theta);
+
+ /* bTemp will hold rotated ball this.positions. You
+ just need to worry about bTemp[1] this.position*/
+ let bTemp = [new p5.Vector(), new p5.Vector()];
+
+ /* this ball's this.position is relative to the other
+ so you can use the vector between them (bVect) as the
+ reference point in the rotation expressions.
+ bTemp[0].this.position.x and bTemp[0].this.position.y will initialize
+ automatically to 0.0, which is what you want
+ since b[1] will rotate around b[0] */
+ bTemp[1].x = cosine * distanceVect.x + sine * distanceVect.y;
+ bTemp[1].y = cosine * distanceVect.y - sine * distanceVect.x;
+
+ // rotate Temporary velocities
+ let vTemp = [new p5.Vector(), new p5.Vector()];
+
+ vTemp[0].x = cosine * this.velocity.x + sine * this.velocity.y;
+ vTemp[0].y = cosine * this.velocity.y - sine * this.velocity.x;
+ vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y;
+ vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x;
+
+ /* Now that velocities are rotated, you can use 1D
+ conservation of momentum equations to calculate
+ the final this.velocity along the x-axis. */
+ let vFinal = [new p5.Vector(), new p5.Vector()];
+
+ // final rotated this.velocity for b[0]
+ vFinal[0].x =
+ ((this.m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) /
+ (this.m + other.m);
+ vFinal[0].y = vTemp[0].y;
+
+ // final rotated this.velocity for b[0]
+ vFinal[1].x =
+ ((other.m - this.m) * vTemp[1].x + 2 * this.m * vTemp[0].x) /
+ (this.m + other.m);
+ vFinal[1].y = vTemp[1].y;
+
+ // hack to avoid clumping
+ bTemp[0].x += vFinal[0].x;
+ bTemp[1].x += vFinal[1].x;
+
+ /* Rotate ball this.positions and velocities back
+ Reverse signs in trig expressions to rotate
+ in the opposite direction */
+ // rotate balls
+ let bFinal = [new p5.Vector(), new p5.Vector()];
+
+ bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
+ bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
+ bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
+ bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
+
+ // update balls to screen this.position
+ other.position.x = this.position.x + bFinal[1].x;
+ other.position.y = this.position.y + bFinal[1].y;
+
+ this.position.add(bFinal[0]);
+
+ // update velocities
+ this.velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
+ this.velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
+ other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y;
+ other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x;
+ }
+ }
+
+ display() {
+ noStroke();
+ fill(204);
+ ellipse(this.position.x, this.position.y, this.r * 2, this.r * 2);
+ }
+}
+let balls = [new Ball(100, 400, 20), new Ball(700, 400, 80)];
+console.log(balls);
+function setup() {
+ createCanvas(710, 400);
+}
+
+function draw() {
+ background(51);
+ for (let i = 0; i < balls.length; i++) {
+ let b = balls[i];
+ b.update();
+ b.display();
+ b.checkBoundaryCollision();
+ balls[0].checkCollision(balls[1]);
+ }
+}
diff --git a/src/data/examples/zh-Hans/13_Motion/07_Circle_Collision.js b/src/data/examples/zh-Hans/13_Motion/07_Circle_Collision.js
new file mode 100644
index 0000000000..876bc23d6e
--- /dev/null
+++ b/src/data/examples/zh-Hans/13_Motion/07_Circle_Collision.js
@@ -0,0 +1,145 @@
+/*
+ * @name Circle Collision
+ * @frame 710,400 (optional)
+ * @description This is a port of the "Circle Collision" example from processing.org/examples
This example uses vectors for better visualization of physical Quantity
+ */
+class Ball {
+ constructor(x, y, r) {
+ this.position = new p5.Vector(x, y);
+ this.velocity = p5.Vector.random2D();
+ this.velocity.mult(3);
+ this.r = r;
+ this.m = r * 0.1;
+ }
+ update() {
+ this.position.add(this.velocity);
+ }
+
+ checkBoundaryCollision() {
+ if (this.position.x > width - this.r) {
+ this.position.x = width - this.r;
+ this.velocity.x *= -1;
+ } else if (this.position.x < this.r) {
+ this.position.x = this.r;
+ this.velocity.x *= -1;
+ } else if (this.position.y > height - this.r) {
+ this.position.y = height - this.r;
+ this.velocity.y *= -1;
+ } else if (this.position.y < this.r) {
+ this.position.y = this.r;
+ this.velocity.y *= -1;
+ }
+ }
+
+ checkCollision(other) {
+ // Get distances between the balls components
+ let distanceVect = p5.Vector.sub(other.position, this.position);
+
+ // Calculate magnitude of the vector separating the balls
+ let distanceVectMag = distanceVect.mag();
+
+ // Minimum distance before they are touching
+ let minDistance = this.r + other.r;
+
+ if (distanceVectMag < minDistance) {
+ let distanceCorrection = (minDistance - distanceVectMag) / 2.0;
+ let d = distanceVect.copy();
+ let correctionVector = d.normalize().mult(distanceCorrection);
+ other.position.add(correctionVector);
+ this.position.sub(correctionVector);
+
+ // get angle of distanceVect
+ let theta = distanceVect.heading();
+ // precalculate trig values
+ let sine = sin(theta);
+ let cosine = cos(theta);
+
+ /* bTemp will hold rotated ball this.positions. You
+ just need to worry about bTemp[1] this.position*/
+ let bTemp = [new p5.Vector(), new p5.Vector()];
+
+ /* this ball's this.position is relative to the other
+ so you can use the vector between them (bVect) as the
+ reference point in the rotation expressions.
+ bTemp[0].this.position.x and bTemp[0].this.position.y will initialize
+ automatically to 0.0, which is what you want
+ since b[1] will rotate around b[0] */
+ bTemp[1].x = cosine * distanceVect.x + sine * distanceVect.y;
+ bTemp[1].y = cosine * distanceVect.y - sine * distanceVect.x;
+
+ // rotate Temporary velocities
+ let vTemp = [new p5.Vector(), new p5.Vector()];
+
+ vTemp[0].x = cosine * this.velocity.x + sine * this.velocity.y;
+ vTemp[0].y = cosine * this.velocity.y - sine * this.velocity.x;
+ vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y;
+ vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x;
+
+ /* Now that velocities are rotated, you can use 1D
+ conservation of momentum equations to calculate
+ the final this.velocity along the x-axis. */
+ let vFinal = [new p5.Vector(), new p5.Vector()];
+
+ // final rotated this.velocity for b[0]
+ vFinal[0].x =
+ ((this.m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) /
+ (this.m + other.m);
+ vFinal[0].y = vTemp[0].y;
+
+ // final rotated this.velocity for b[0]
+ vFinal[1].x =
+ ((other.m - this.m) * vTemp[1].x + 2 * this.m * vTemp[0].x) /
+ (this.m + other.m);
+ vFinal[1].y = vTemp[1].y;
+
+ // hack to avoid clumping
+ bTemp[0].x += vFinal[0].x;
+ bTemp[1].x += vFinal[1].x;
+
+ /* Rotate ball this.positions and velocities back
+ Reverse signs in trig expressions to rotate
+ in the opposite direction */
+ // rotate balls
+ let bFinal = [new p5.Vector(), new p5.Vector()];
+
+ bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
+ bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
+ bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
+ bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
+
+ // update balls to screen this.position
+ other.position.x = this.position.x + bFinal[1].x;
+ other.position.y = this.position.y + bFinal[1].y;
+
+ this.position.add(bFinal[0]);
+
+ // update velocities
+ this.velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
+ this.velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
+ other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y;
+ other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x;
+ }
+ }
+
+ display() {
+ noStroke();
+ fill(204);
+ ellipse(this.position.x, this.position.y, this.r * 2, this.r * 2);
+ }
+}
+let balls = [new Ball(100, 400, 20), new Ball(700, 400, 80)];
+console.log(balls);
+function setup() {
+ createCanvas(710, 400);
+}
+
+function draw() {
+ background(51);
+ for (let i = 0; i < balls.length; i++) {
+ let b = balls[i];
+ b.update();
+ b.display();
+ b.checkBoundaryCollision();
+ balls[0].checkCollision(balls[1]);
+ }
+}