为什么这个不画轨道,只画椭圆呢?
Why does't this draw an orbit and just draws an ellipse?
我开始使用 p5.js 创建一个非常粗略的太阳系模拟,受到 Daniel Shiffman 的启发视频。
我试图通过保存行星在数组中的位置来绘制每个行星的轨道,然后使用 for 循环遍历它们并在每个保存的位置画一个圆圈。
除非它不起作用!
它应该有效,因为为了确保这是最好的方法,我搜索并进入了另一个 Daniel Shiffman 的视频,显然它适用于他,但不幸的是不适合我!
有人可以告诉我我正在做的事情有什么问题吗? (抱歉我的英语不好)
下面是代码片段!
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>
当你写 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>
我开始使用 p5.js 创建一个非常粗略的太阳系模拟,受到 Daniel Shiffman 的启发视频。
我试图通过保存行星在数组中的位置来绘制每个行星的轨道,然后使用 for 循环遍历它们并在每个保存的位置画一个圆圈。
除非它不起作用!
它应该有效,因为为了确保这是最好的方法,我搜索并进入了另一个 Daniel Shiffman 的视频,显然它适用于他,但不幸的是不适合我!
有人可以告诉我我正在做的事情有什么问题吗? (抱歉我的英语不好)
下面是代码片段!
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>
当你写 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>