Почему это не рисует орбиту и просто др aws эллипс? - PullRequest
2 голосов
/ 16 февраля 2020

Я начал создавать очень грубую симуляцию солнечной системы, используя p5. js, вдохновленный видео Даниэля Шиффмана .

Я пытался нарисовать орбиту для каждого pl anet, сохранив позиции, в которых pl anet находился в массиве, а затем использовал для l oop, чтобы выполнить их итерацию и нарисовать круг в каждая сохраненная позиция.

За исключением того, что это не работает!

Это должно было сработать, потому что, чтобы быть уверенным, что это был лучший способ сделать это, я искал и получил другой из Видео Даниэля Шиффмана , и, очевидно, это сработало для него, но, к сожалению, не для меня!

Может кто-нибудь сказать мне, в чем проблема с тем, что я делаю. (Извините за мой бедный Энгли sh)

Здесь есть код во фрагменте!

class Planet
{
    constructor(orbitCenter, color, mass, velocityLimit)
    {
        this.orbitCenter = orbitCenter;
        this.color = color;
        this.mass = mass;
        this.velocityLimit = velocityLimit;

        this.position = createVector(width/2, 50);
        this.radius = 15;
        this.velocity = createVector(30, 10);
        this.acceleration = createVector(0.0, 0.0);
        this.pathPoints = [];
    }

    render() 
    {
        const diameter = this.radius * 2;
        ellipseMode(CENTER);
        noStroke();
        fill(this.color);
        ellipse(this.position.x, this.position.y, diameter);

        if(this.pathPoints.length > 1000) 
        {
            this.pathPoints.splice(0, 1);
        }

        for(let i = 0; i < this.pathPoints.length; i++)
        {
            let pos = this.pathPoints[i];
            fill(255);
            ellipse(pos.x, pos.y, 5, 5);
        }
    }

    update() 
    {     
        this.position.add(this.velocity);
        this.velocity.add(this.acceleration);
        this.acceleration = createVector(this.orbitCenter.x, this.orbitCenter.y)
            .sub(this.position)
            .mult(this.mass);
        this.velocity.limit(this.velocityLimit);
        this.pathPoints.push(this.position);
    }
}

class Star
{
    constructor(color, position, diameter) 
    {
        this.color = color;
        this.position = position;
        this.diameter = diameter;
    }

    render()
    {
        fill(this.color);
        noStroke();
        ellipse(this.position.x, this.position.y, this.diameter);
    }
}

let sun;
let earth, mars;
let sunDiameter = 40;

function setup()
{
    createCanvas(windowWidth, windowHeight);
    frameRate(60);

    let sunPos = createVector(width/2, height/2);
    sun = new Star(color(255, 255, 0), sunPos, sunDiameter);

    earth = new Planet(sunPos, color(0, 100, 255), 0.0008, 4.5);
    mars = new Planet(sunPos, color(255, 100, 0), 0.0004, 5);
}

let toggleOrbit = true;
function draw()
{
    background(0);
    sun.render();

    earth.render();
    mars.render();

    if(toggleOrbit)
    {
        earth.update();
        mars.update();
    }
    
}

function windowResized()
{
    resizeCanvas(windowWidth, windowHeight);
    setup();
}

function keyPressed(e)
{
    if(e.key == ' ')
    {
        toggleOrbit = !toggleOrbit;
    }
    
    if(e.key == 'c')
    {
        console.log(earth.getPathPoints());
    }
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Gravity Simulation</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js"></script>

        <style>
            *
            {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }

            body
            {
                width: 100vw;
                height: 100vh;
                display: flex;
                align-items: center;
                justify-content: center;
            }
        </style>
    </head>
    <body>
        <script src="main.js"></script>
    </body>
</html>

1 Ответ

3 голосов
/ 16 февраля 2020

Когда вы пишете this.pathPoints.push(this.position), вы в конечном итоге сохраняете ссылку на объект this.position, а не на его значения X и Y, поэтому, когда приходит время рисования орбиты, каждый раз используется текущее значение this.position , Если вместо этого вы сохраните значения X и Y, вы получите желаемый результат; замените

this.pathPoints.push(this.position);

на

this.pathPoints.push({
    x: this.position.x,
    y: this.position.y
})

, и вы увидите, что орбита нарисована.

class Planet
{
    constructor(orbitCenter, color, mass, velocityLimit)
    {
        this.orbitCenter = orbitCenter;
        this.color = color;
        this.mass = mass;
        this.velocityLimit = velocityLimit;

        this.position = createVector(width/2, 50);
        this.radius = 15;
        this.velocity = createVector(30, 10);
        this.acceleration = createVector(0.0, 0.0);
        this.pathPoints = [];
    }

    render() 
    {
        const diameter = this.radius * 2;
        ellipseMode(CENTER);
        noStroke();
        fill(this.color);
        ellipse(this.position.x, this.position.y, diameter);

        if(this.pathPoints.length > 1000) 
        {
            this.pathPoints.splice(0, 1);
        }

        for(let i = 0; i < this.pathPoints.length; i++)
        {
            let pos = this.pathPoints[i];
            fill(255);
            ellipse(pos.x, pos.y, 5, 5);
        }
    }

    update() 
    {     
        this.position.add(this.velocity);
        this.velocity.add(this.acceleration);
        this.acceleration = createVector(this.orbitCenter.x, this.orbitCenter.y)
            .sub(this.position)
            .mult(this.mass);
        this.velocity.limit(this.velocityLimit);
        this.pathPoints.push({
            x: this.position.x,
            y: this.position.y
        })
    }
}

class Star
{
    constructor(color, position, diameter) 
    {
        this.color = color;
        this.position = position;
        this.diameter = diameter;
    }

    render()
    {
        fill(this.color);
        noStroke();
        ellipse(this.position.x, this.position.y, this.diameter);
    }
}

let sun;
let earth, mars;
let sunDiameter = 40;

function setup()
{
    createCanvas(windowWidth, windowHeight);
    frameRate(60);

    let sunPos = createVector(width/2, height/2);
    sun = new Star(color(255, 255, 0), sunPos, sunDiameter);

    earth = new Planet(sunPos, color(0, 100, 255), 0.0008, 4.5);
    mars = new Planet(sunPos, color(255, 100, 0), 0.0004, 5);
}

let toggleOrbit = true;
function draw()
{
    background(0);
    sun.render();

    earth.render();
    mars.render();

    if(toggleOrbit)
    {
        earth.update();
        mars.update();
    }
    
}

function windowResized()
{
    resizeCanvas(windowWidth, windowHeight);
    setup();
}

function keyPressed(e)
{
    if(e.key == ' ')
    {
        toggleOrbit = !toggleOrbit;
    }
    
    if(e.key == 'c')
    {
        console.log(earth.getPathPoints());
    }
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Gravity Simulation</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js"></script>

        <style>
            *
            {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }

            body
            {
                width: 100vw;
                height: 100vh;
                display: flex;
                align-items: center;
                justify-content: center;
            }
        </style>
    </head>
    <body>
        <script src="main.js"></script>
    </body>
</html>
...