commit
d6e7323ec2
7 changed files with 463 additions and 0 deletions
@ -0,0 +1,2 @@ |
||||
.idea |
||||
|
@ -0,0 +1,6 @@ |
||||
{ |
||||
"display_name": "Fibonacci", |
||||
"info_text": "Standing picture of the Fibonacci sequence", |
||||
"visible": false, |
||||
"tags": ["Maths"] |
||||
} |
@ -0,0 +1,18 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js" type="text/javascript"></script> |
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js" type="text/javascript"></script> |
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js" type="text/javascript"></script> |
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" type="text/javascript"></script> |
||||
<script src="scripts/lib/BenjoLibrary.js" type="text/javascript"></script> |
||||
<script src="scripts/sketch.js" type="text/javascript"></script> |
||||
<link href="styles.css" rel="stylesheet"> |
||||
<link href="pictures/favicon.ico" rel="icon" type="image/x-icon"> |
||||
<title>Fibonacci</title> |
||||
</head> |
||||
<body> |
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,369 @@ |
||||
var TOP = 1; |
||||
var RIGHT = 2 |
||||
var BOTTOM = 3; |
||||
var LEFT = 4; |
||||
var TOP_RIGHT = 5; |
||||
var BOTTOM_RIGHT = 6; |
||||
var BOTTOM_LEFT = 7; |
||||
var TOP_LEFT = 8; |
||||
|
||||
var wWidth = window.innerWidth; |
||||
var wHeight = window.innerHeight; |
||||
var oldWHeight; |
||||
var oldWWidth; |
||||
|
||||
function updateVars(){ |
||||
oldWWidth = wWidth; |
||||
oldWHeight = wHeight; |
||||
wWidth = window.innerWidth; |
||||
wHeight = window.innerHeight; |
||||
} |
||||
|
||||
function collisionDetection(obj0, obj1){ |
||||
|
||||
var sp = strokePadding; |
||||
if (sp == null) sp = 0; |
||||
|
||||
if (obj0.isEllipse && obj1.isRectangle){ |
||||
|
||||
//Ball
|
||||
var b = obj0; |
||||
|
||||
//Rectangle
|
||||
var r = obj1; |
||||
|
||||
for (var i = 0; i < TWO_PI; i += PI / 32){ |
||||
|
||||
/* Check every borderpoint of the ball beginning |
||||
at the top in clock direction up to top again */ |
||||
|
||||
// Ball Center X
|
||||
var bcx = b.x; |
||||
|
||||
// Ball Center Y
|
||||
var bcy = b.y; |
||||
|
||||
// Ball Border X
|
||||
var bbx = b.x + sin(i) * b.r; |
||||
|
||||
// Ball Border Y inverted because Y = 0 is the TOP of the screen
|
||||
var bby = b.y - cos(i) * b.r; |
||||
|
||||
// Rectangle Width
|
||||
var rW = r.width + 2 * sp; |
||||
|
||||
// Rectangle Height
|
||||
var rH = r.height + 2 * sp; |
||||
|
||||
// Rectangle Border X
|
||||
var rX = r.x - sp; |
||||
|
||||
// Rectangle Border Y
|
||||
var rY = r.y - sp; |
||||
|
||||
// Objects touch
|
||||
if (bbx > rX && bbx < rX + rW |
||||
&& bby > rY && bby < rY + rH){ |
||||
|
||||
// STRAIGHT FACES //
|
||||
|
||||
//Top/Bottom touch
|
||||
if (bcx > rX && bcx < rX + rW){
|
||||
|
||||
//Top touch
|
||||
if (b.v.y > 0) return {isTouching: true, location: TOP}; |
||||
|
||||
//Bottom touch
|
||||
if (b.v.y < 0) return {isTouching: true, location: BOTTOM}; |
||||
} |
||||
|
||||
//Left/Right touch
|
||||
if (bcy > rY && bcy < rY + rH){ |
||||
|
||||
//Left touch
|
||||
if (b.v.x > 0) return {isTouching: true, location: LEFT}; |
||||
|
||||
//Right touch
|
||||
if (b.v.x < 0) return {isTouching: true, location: RIGHT}; |
||||
|
||||
} |
||||
|
||||
// CORNERS //
|
||||
|
||||
// BOTTOM Left/Right
|
||||
if (i > 0 && i <= PI / 2) return {isTouching: true, location: BOTTOM_LEFT}; |
||||
|
||||
//LEFT Bottom/Top
|
||||
if (i > PI / 2 && i <= PI) return {isTouching: true, location: TOP_LEFT}; |
||||
|
||||
//TOP Left/Right
|
||||
if (i > PI && i <= PI + PI / 2) return {isTouching: true, location: TOP_RIGHT}; |
||||
|
||||
//RIGHT Bottom/Top
|
||||
if (i > PI + PI / 2 && i <= TWO_PI) return {isTouching: true, location: BOTTOM_RIGHT}; |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
if (obj0.isEllipse && obj1.isEllipse){ |
||||
|
||||
//Ball 1
|
||||
var b1 = obj0; |
||||
|
||||
//Ball 2
|
||||
var b2 = obj1; |
||||
|
||||
//Balls are close to each other
|
||||
if (b1.x + b1.r > b2.x - b2.r |
||||
&& b1.x - b1.r < b2.x + b2.r |
||||
&& b1.y + b1.r > b2.y - b2.r |
||||
&& b1.y - b1.r < b2.y + b2.r){ |
||||
|
||||
var distance = sqrt(pow(b1.x - b2.x, 2) + pow(b1.y - b2.y, 2)); |
||||
|
||||
if (distance < b1.r + b2.r) return {isTouching: true}; |
||||
} |
||||
} |
||||
return {isTouching: false, location: 0}; |
||||
} |
||||
|
||||
function performCollision(obj0, obj1, collision){ |
||||
if (obj0.isEllipse){ |
||||
|
||||
var ball = obj0; |
||||
|
||||
//Ball collides with frameborder
|
||||
if (obj1.isFrameborder){ |
||||
switch (collision.location){ |
||||
case BOTTOM: |
||||
ball.v.y *= -1; |
||||
break; |
||||
case LEFT: |
||||
case RIGHT: |
||||
ball.v.x *= -1; |
||||
break; |
||||
} |
||||
if (testMode && collision.location == TOP) ball.v.y *= -1; |
||||
ball.move(); |
||||
} |
||||
|
||||
//Ball collides with any brick
|
||||
if (obj1.isBrick){ |
||||
switch (collision.location){ |
||||
case TOP: |
||||
case BOTTOM: |
||||
ball.v.y *= -1; |
||||
ball.move(); |
||||
return; |
||||
case LEFT: |
||||
case RIGHT: |
||||
ball.v.x *= -1; |
||||
ball.move(); |
||||
return; |
||||
case TOP_LEFT: |
||||
var cornerX = obj1.x; |
||||
var cornerY = obj1.y; |
||||
break; |
||||
case TOP_RIGHT: |
||||
var cornerX = obj1.x + obj1.width; |
||||
var cornerY = obj1.y; |
||||
break; |
||||
case BOTTOM_LEFT: |
||||
var cornerX = obj1.x; |
||||
var cornerY = obj1.y + obj1.height; |
||||
break; |
||||
case BOTTOM_RIGHT: |
||||
var cornerX = obj1.x + obj1.width; |
||||
var cornerY = obj1.y + obj1.height; |
||||
break; |
||||
} |
||||
|
||||
var nx = ball.x - cornerX; |
||||
var ny = ball.y - cornerY; |
||||
var length = sqrt(nx * nx + ny * ny); |
||||
nx /= length; |
||||
ny /= length; |
||||
|
||||
var projection = ball.v.x * nx + ball.v.y * ny; |
||||
ball.v.x = ball.v.x - 2 * projection * nx; |
||||
ball.v.y = ball.v.y - 2 * projection * ny; |
||||
|
||||
ball.move(); |
||||
|
||||
} |
||||
|
||||
//Ball collides with paddleboard
|
||||
if (obj1.isPaddle){ |
||||
switch (collision.location){ |
||||
case TOP: |
||||
case TOP_LEFT: |
||||
case TOP_RIGHT: |
||||
ball.v.x = ball.calcVelocityX(obj1, ball.v.x); |
||||
ball.v.y = -ball.calcVelocityY(); |
||||
ball.move(); |
||||
return; |
||||
case LEFT: |
||||
case RIGHT: |
||||
ball.v.x *= -1; |
||||
ball.move(); |
||||
return; |
||||
case BOTTOM_LEFT: |
||||
var cornerX = obj1.x; |
||||
var cornerY = obj1.y + obj1.height; |
||||
break; |
||||
case BOTTOM_RIGHT: |
||||
var cornerX = obj1.x + obj1.width; |
||||
var cornerY = obj1.y + obj1.height; |
||||
break; |
||||
} |
||||
var nx = ball.x - cornerX; |
||||
var ny = ball.y - cornerY; |
||||
var length = sqrt(nx * nx + ny * ny); |
||||
nx /= length; |
||||
ny /= length; |
||||
|
||||
var projection = ball.v.x * nx + ball.v.y * ny; |
||||
ball.v.x = ball.v.x - 2 * projection * nx; |
||||
ball.v.y = ball.v.y - 2 * projection * ny; |
||||
|
||||
ball.move(); |
||||
} |
||||
|
||||
//Ball collides with other ball
|
||||
if (obj1.isEllipse){ |
||||
|
||||
//Ball 1
|
||||
var b1 = obj0; |
||||
|
||||
//Ball 2
|
||||
var b2 = obj1; |
||||
|
||||
//Set mass equal to radius of each ball
|
||||
b1.mass = b1.r; |
||||
b2.mass = b2.r; |
||||
|
||||
//Colliding angle of ball 1 to ball 2 using arc tan of both x and y differences
|
||||
var collisionAngle = atan2((b2.y - b1.y), (b2.x - b1.x)); |
||||
|
||||
//Converting directions of velocity vector of balls into angles
|
||||
var d1 = atan2(b1.v.y, b1.v.x); |
||||
var d2 = atan2(b2.v.y, b2.v.x); |
||||
|
||||
//Ignoring mass effects new velocites are simply magnitude multiplied with value of angle differences
|
||||
var newXspeed1 = b1.v.mag * cos(d1 - collisionAngle); |
||||
var newYspeed1 = b1.v.mag * sin(d1 - collisionAngle); |
||||
var newXspeed2 = b2.v.mag * cos(d2 - collisionAngle); |
||||
var newYspeed2 = b2.v.mag * sin(d2 - collisionAngle); |
||||
|
||||
//According to the principle of linear momentum, kinetic energy stays the same after collision, so velocities are now related to masses
|
||||
var finalXspeed1 = ((b1.mass - b2.mass) * newXspeed1 + b2.mass * 2 * newXspeed2) / (b1.mass + b2.mass); |
||||
var finalYspeed1 = newYspeed1; |
||||
var finalXspeed2 = (b1.mass * 2 * newXspeed1 + (b2.mass - b1.mass) * newXspeed2) / (b1.mass + b2.mass); |
||||
var finalYspeed2 = newYspeed2; |
||||
|
||||
//Values of collisionAngle
|
||||
var cosAngle = cos(collisionAngle); |
||||
var sinAngle = sin(collisionAngle); |
||||
|
||||
//To also keep velocites relative to pure collisionAngle, subtract sin*x from cos*x and add sin*y to cos*y because coordSystem has y = 0 on the top
|
||||
var u1x = cosAngle * finalXspeed1 - sinAngle * finalYspeed1; |
||||
var u1y = sinAngle * finalXspeed1 + cosAngle * finalYspeed1; |
||||
var u2x = cosAngle * finalXspeed2 - sinAngle * finalYspeed2; |
||||
var u2y = sinAngle * finalXspeed2 + cosAngle * finalYspeed2; |
||||
|
||||
//Set new velocities to both balls
|
||||
b1.v.x = u1x; |
||||
b1.v.y = u1y; |
||||
b2.v.x = u2x; |
||||
b2.v.y = u2y; |
||||
|
||||
//Update magnitude
|
||||
b1.v.mag = sqrt(pow(b1.v.x, 2) + pow(b1.v.y, 2)); |
||||
b2.v.mag = sqrt(pow(b2.v.x, 2) + pow(b2.v.y, 2)); |
||||
|
||||
|
||||
//Move balls one vx/vy forward to avoid double inverting collision detection
|
||||
b1.x += b1.v.x; |
||||
b1.y += b1.v.y; |
||||
b2.x += b2.v.x; |
||||
b2.y += b2.v.y; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
function toTimeString(time, hoursWanted){ |
||||
|
||||
var time = floor(time / 10); |
||||
|
||||
var hs = String(floor(time % 100)); |
||||
var fs = String(floor((time / 100) % 60)); |
||||
|
||||
if (hoursWanted){ |
||||
var min = String(floor(((time / 100) / 60) % 60)); |
||||
var hr = String(floor(((time / 100) / 60) / 60)); |
||||
|
||||
if (hs.length < 2) hs = "0" + hs; |
||||
if (fs.length < 2) fs = "0" + fs; |
||||
if (min.length < 2) min = "0" + min; |
||||
if (hr.length < 2) hr = "0" + hr; |
||||
|
||||
var timeString = hr + ":" + min + ":" + fs + ":" + hs; |
||||
} else { |
||||
var min = String(floor(((time / 100) / 60) % 60)); |
||||
|
||||
if (hs.length < 2) hs = "0" + hs; |
||||
if (fs.length < 2) fs = "0" + fs; |
||||
if (min.length < 2) min = "0" + min; |
||||
|
||||
var timeString = min + ":" + fs + ":" + hs; |
||||
} |
||||
|
||||
|
||||
|
||||
return timeString; |
||||
} |
||||
|
||||
|
||||
function setCookie(name, value, years){ |
||||
var expires = ""; |
||||
if (years){ |
||||
var date = new Date(); |
||||
date.setTime(date.getTime() + (years * 365 * 24 * 60 * 60 * 1000)); |
||||
expires = "; expires=" + date.toUTCString(); |
||||
} |
||||
document.cookie = name + "=" + value + expires + "; path=/"; |
||||
} |
||||
|
||||
function getCookie(name){ |
||||
var nameEQ = name + "="; |
||||
var ca = document.cookie.split(';'); |
||||
for (var i = 0; i < ca.length; i++){ |
||||
var c = ca[i]; |
||||
while (c.charAt(0) == ' ') c = c.substring(1, c.length); |
||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
function deleteCookies(){ |
||||
for (var i = 0; i < arguments.length; i++) setCookie(arguments[i], "", -1); |
||||
} |
||||
|
||||
function deleteAllCookies(){ |
||||
var cookies = document.cookie.split(";"); |
||||
for (var i = 0; i < cookies.length; i++) deleteCookies(cookies[i].split("=")[0]); |
||||
} |
||||
|
||||
Array.prototype.shuffle = function(){ |
||||
let currentIndex = this.length, temporaryValue, randomIndex; |
||||
while (0 != currentIndex) { |
||||
randomIndex = Math.floor(Math.random() * currentIndex); |
||||
currentIndex -= 1; |
||||
temporaryValue = this[currentIndex]; |
||||
this[currentIndex] = this[randomIndex]; |
||||
this[randomIndex] = temporaryValue; |
||||
} |
||||
} |
@ -0,0 +1,63 @@ |
||||
let center; |
||||
|
||||
function setup(){ |
||||
setFrameRate(60); |
||||
createCanvas(window.innerWidth, window.innerHeight); |
||||
center = createVector(window.innerWidth / 2, window.innerHeight / 2); |
||||
noFill(); |
||||
} |
||||
|
||||
function draw(){ |
||||
clear(); |
||||
background(40, 40, 42); |
||||
for (let i = 6; i < Infinity; i++){ |
||||
let quadrant = (i + 1) % 4 + 1; |
||||
let f = fibo(i); |
||||
let x = 0, y = 0, startAngle, endAngle, a, b; |
||||
if (quadrant == 1){ |
||||
for (let j = i - 3; j > 0; j -= 4) x -= fibo(j); |
||||
for (let k = i; k > 0; k -= 4) y -= fibo(k); |
||||
startAngle = -HALF_PI; |
||||
endAngle = TWO_PI; |
||||
a = 0; |
||||
b = 1; |
||||
} |
||||
if (quadrant == 2){ |
||||
for (let j = i; j > 0; j -= 4) x -= fibo(j); |
||||
for (let k = i - 1; k > 0; k -= 4) y -= fibo(k); |
||||
startAngle = PI; |
||||
endAngle = -HALF_PI; |
||||
a = 1; |
||||
b = 1; |
||||
} |
||||
if (quadrant == 3){ |
||||
for (let j = i - 1; j > 0; j -= 4) x -= fibo(j); |
||||
for (let k = i - 4; k > 0; k -= 4) y += fibo(k); |
||||
startAngle = HALF_PI; |
||||
endAngle = PI; |
||||
a = 1; |
||||
b = 0; |
||||
} |
||||
if (quadrant == 4){ |
||||
for (let j = i - 4; j > 0; j -= 4) x += fibo(j); |
||||
for (let k = i - 3; k > 0; k -= 4) y -= fibo(k); |
||||
startAngle = 0; |
||||
endAngle = HALF_PI; |
||||
a = 0; |
||||
b = 0; |
||||
} |
||||
stroke(150); |
||||
strokeWeight(1); |
||||
rect(center.x + x, center.y + y, f, f); |
||||
stroke("#FF0000"); |
||||
strokeWeight(3); |
||||
arc(center.x + x + a * f, center.y + y + b * f, f * 2, f * 2, startAngle, endAngle); |
||||
if (fibo(i) > width) break; |
||||
} |
||||
} |
||||
|
||||
function fibo(i){ |
||||
if (i == 1 || i == 2) return 1; |
||||
return fibo(i - 1) + fibo(i - 2); |
||||
} |
||||
|
@ -0,0 +1,5 @@ |
||||
a:link, a:hover, a:active, a:visited{color: #000;} |
||||
|
||||
body{margin: 0; padding: 0;} |
||||
|
||||
canvas{margin: 0; padding: 0; border: none; display: block;} |
After Width: | Height: | Size: 58 KiB |
Loading…
Reference in new issue