xxxxxxxxxx
218
class Car {
constructor(x, y, th, v){
this.x = x;
this.y = y;
this.th = th;
this.v = v;
this.rays = [];
}
draw(){
push()
translate(this.x, this.y)
rotate(this.th)
rect(0, 0, 20, 10)
pop()
}
move(){
this.x += this.v * cos(this.th);
this.y += this.v * sin(this.th)
}
steer() {
// Right eye
let rightDist = 10000;
let pt = {
x: this.x,
y: this.y
};
// Raymarching
for(let step = 0; step < 10; step++){
for(let i = 0; i < track.length; i++){
if(i < track.length - 2 && track.length > 2){
let p1 = {
x: track[i].left.x,
y: track[i].left.y
}
let p2 = {
x: track[i+1].left.x,
y: track[i+1].left.y
}
rightDist = Math.min(lineSDF(pt, p1, p2), rightDist);
p1 = {
x: track[i].right.x,
y: track[i].right.y
}
p2 = {
x: track[i+1].right.x,
y: track[i+1].right.y
}
rightDist = Math.min(lineSDF(pt, p1, p2), rightDist);
}
if(rightDist < 0.1) {
break
}
}
pt.x += rightDist * cos(this.th + PI/4)
pt.y += rightDist * sin(this.th + PI/4)
}
line(this.x, this.y, pt.x, pt.y)
let distToLeft = dist(this.x, this.y, pt.x, pt.y)
// Left Eye
// Right eye
let leftDist = 10000;
pt = {
x: this.x,
y: this.y
};
// Raymarching
for(let step = 0; step < 10; step++){
for(let i = 0; i < track.length; i++){
if(i < track.length - 2 && track.length > 2){
let p1 = {
x: track[i].left.x,
y: track[i].left.y
}
let p2 = {
x: track[i+1].left.x,
y: track[i+1].left.y
}
leftDist = Math.min(lineSDF(pt, p1, p2), leftDist);
p1 = {
x: track[i].right.x,
y: track[i].right.y
}
p2 = {
x: track[i+1].right.x,
y: track[i+1].right.y
}
leftDist = Math.min(lineSDF(pt, p1, p2), leftDist);
}
if(leftDist < 0.1) {
break
}
}
pt.x += leftDist * cos(this.th - PI/4)
pt.y += leftDist * sin(this.th - PI/4)
}
line(this.x, this.y, pt.x, pt.y)
let distToRight = dist(this.x, this.y, pt.x, pt.y)
// Turn the car
this.th += -(distToRight - distToLeft) / 1000
}
}
function setup() {
createCanvas(800, 700);
// translate(200, 200)
track = []
trackWidth = 45;
rectMode(CENTER)
// generateTrack()
car = new Car(0, 0, 0, 0)
}
function draw() {
background(200)
strokeWeight(5)
if(mouseIsPressed && frameCount % 10 == 0 && track.length > 0 && dist(mouseX, mouseY, track[track.length-1].x, track[track.length-1].y) > 20) {
track.push(
{x: mouseX,
y: mouseY
}
);
console.log(frameRate())
// Create the track
for(let i = 0; i < track.length; i++){
if(i < track.length-1){
let th = atan2( track[i+1].y - track[i].y, track[i+1].x - track[i].x )
if( i == 0) car.th = th;
track[i].left = {
x: (track[i].x + track[i+1].x)/2 - trackWidth*sin(th),
y: (track[i].y + track[i+1].y)/2 + trackWidth*cos(th)
}
track[i].right = {
x: (track[i].x + track[i+1].x)/2 + trackWidth*sin(th),
y: (track[i].y + track[i+1].y)/2 - trackWidth*cos(th)
}
}
}
}
// Draw
for(let i = 0; i < track.length; i++){
point(track[i].x, track[i].y)
if(i < track.length-2 && track.length > 2){
line(track[i].left.x,
track[i].left.y,
track[i+1].left.x,
track[i+1].left.y);
line(track[i].right.x, track[i].right.y, track[i+1].right.x, track[i+1].right.y);
}
}
car.draw()
car.move()
car.steer()
}
function mousePressed() {
track = []
track.push({x: mouseX, y: mouseY})
car.x = mouseX;
car.y = mouseY;
car.v = 0;
}
function mouseReleased(){
car.v = 2;
}
function lineSDF(p, a, b) {
let ba = {
x: b.x - a.x,
y: b.y - a.y
}
let pa = {
x: p.x - a.x,
y: p.y - a.y
}
let h = constrain(dot(pa, ba)/dot(ba, ba), 0, 1)
let d = vMag(vSub(pa, scalarMult(h, ba)))
return d;
}
function dot(a, b){
let d = a.x*b.x + a.y*b.y;
return d;
}
function scalarMult(s, v){
return {
x: s*v.x,
y: s*v.y
}
}
function vSub(a, b){
return {
x: a.x - b.x,
y: a.y - b.y
}
}
function vMag(v){
return sqrt(v.x**2 + v.y**2)
}