Skip to content

Instantly share code, notes, and snippets.

@tomowarkar
Last active April 5, 2021 21:22
Show Gist options
  • Save tomowarkar/48803a569d7ae58bd54b465db2d9a53a to your computer and use it in GitHub Desktop.
Save tomowarkar/48803a569d7ae58bd54b465db2d9a53a to your computer and use it in GitHub Desktop.
import p5 from "p5";
const round = (value: number, base: number) =>
Math.round(value * 10 ** base) / 10 ** base;
class Vec2 {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
get string(): string {
return `(${round(this.x, 3)}, ${round(this.y, 3)})`;
}
get length() {
return Math.hypot(this.x, this.y);
}
get normal() {
return new Vec2(-this.y, this.x);
}
add(other: Vec2) {
return new Vec2(this.x + other.x, this.y + other.y);
}
sub(other: Vec2) {
return new Vec2(this.x - other.x, this.y - other.y);
}
mul(n: number) {
return new Vec2(this.x * n, this.y * n);
}
div(n: number) {
return new Vec2(this.x / n, this.y / n);
}
}
class Cell {
position: Vec2;
velocity: Vec2;
acceleration: Vec2;
mass: number;
constructor(x: number, y: number, mass: number) {
this.position = new Vec2(x, y);
this.velocity = new Vec2(0, 0);
this.acceleration = new Vec2(0, 0);
this.mass = mass;
}
get x() {
return this.position.x;
}
get y() {
return this.position.y;
}
get vx() {
return this.velocity.x;
}
get vy() {
return this.velocity.y;
}
get string() {
return `pos: ${this.position.string}, vel: ${this.velocity.string}`;
}
update(dt: number) {
this.acceleration.y = 9.8;
let b = 0.65, // 粘性抵抗係数[N・s/m]
r = Math.exp((-b * dt) / this.mass),
mb = this.mass / b,
resi = this.acceleration.mul(mb),
v = this.velocity.add(resi).mul(r).sub(resi),
d = this.velocity
.add(resi)
.mul(mb * (1 - r))
.sub(resi.mul(dt));
this.position = this.position.add(d);
this.velocity = v;
this.acceleration = new Vec2(0, 0);
}
}
class Drawer {
windowWidth: number = 600;
windowHeight: number = 400;
margin: number = 100;
rx: number = 1;
ry: number = 1;
constructor(width?: number, height?: number, margin?: number) {
if (width) this.windowWidth = width;
if (height) this.windowHeight = height;
if (margin) this.margin = margin;
}
get r() {
return this.windowHeight / this.windowWidth;
}
get width() {
return (this.windowWidth - 2 * this.margin) / this.rx;
}
get height() {
return (this.windowHeight - 2 * this.margin) / this.ry;
}
apply(w: number, h: number) {
this.rx = (this.windowWidth - 2 * this.margin) / w;
this.ry = (this.windowHeight - 2 * this.margin) / h;
}
modify(x: number, y: number) {
return new Vec2(
x * this.rx + this.margin,
this.windowHeight - this.margin - y * this.ry
);
}
}
const sketch = (p: p5) => {
let cells: Cell[] = [new Cell(0, 0, 1)];
let d: Drawer;
let fps = 60;
p.setup = () => {
p.createCanvas(p.windowWidth, p.windowHeight);
d = new Drawer(p.windowWidth, p.windowHeight);
d.apply(20, 20 * d.r);
p.frameRate(fps);
// p.noLoop()
};
const drawCell = (c: Cell) => {
let v = d.modify(c.x, c.y);
p.ellipse(v.x, v.y, 30);
};
const drawGrid = () => {
let p1 = d.modify(0, 0),
p2 = d.modify(d.width, d.height);
p.strokeWeight(1);
p.line(p1.x, p1.y, p1.x, p2.y);
p.line(p1.x, p1.y, p2.x, p1.y);
p.line(p2.x, p1.y, p2.x, p2.y);
p.line(p1.x, p2.y, p2.x, p2.y);
p.strokeWeight(0.2);
for (let i = 1; i < d.width; i++) {
let p3 = d.modify(i, i);
p.line(p3.x, p1.y, p3.x, p2.y);
}
for (let i = 1; i < d.height; i++) {
let p3 = d.modify(i, i);
p.line(p1.x, p3.y, p2.x, p3.y);
}
};
p.draw = () => {
p.background(220);
drawGrid();
cells[0].update(1 / fps);
p.text(cells[0].string, 90, 90);
cells.map((c) => {
drawCell(c);
});
};
p.mouseClicked = () => {
cells[0].position = new Vec2(0, 0);
cells[0].velocity = new Vec2(10, 20);
};
};
export default sketch;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment