[QUOTE=Fatfatfatty;41727125]Fixed my orbits, it was just that the gravity well was static but the object had fairly high mass in comparison to the "planet" which caused it to move oddly
[img]https://dl.dropboxusercontent.com/u/45707598/goodorbit.png[/img][/QUOTE]
Mass shouldn't cause your orbit to break as it did, as DevBug suggested above it is most likely down to using an inaccurate integration method in your simulation (assuming, of course, that all your equations are correct).
-snip- wrong thread
Is this the correct usage of std::move?
[cpp]vector<string> line;
string buf;
while(!file.eof()){
std::getline(file, buf);
line.emplace_back(std::move(buf));
}[/cpp]
How about here, where I pass a vector from one function to the other?
[cpp]Model * mod = new Model(vao, vbo, ebo, elements.size(), std::move(materials));[/cpp]
Materials is a vector, and the Model uses this vector in its functionality (it is a member). The constructor uses the && qualifier.
[QUOTE=Chris220;41728322]Mass shouldn't cause your orbit to break as it did, as DevBug suggested above it is most likely down to using an inaccurate integration method in your simulation (assuming, of course, that all your equations are correct).[/QUOTE]
The object's mass also shouldn't be a variable in the calculation at all.
If you calculate the force and then apply that you just lose accuracy unnecessarily.
[QUOTE=WTF Nuke;41730746]Is this the correct usage of std::move?
[cpp]vector<string> line;
string buf;
while(!file.eof()){
std::getline(file, buf);
line.emplace_back(std::move(buf));
}[/cpp]
How about here, where I pass a vector from one function to the other?
[cpp]Model * mod = new Model(vao, vbo, ebo, elements.size(), std::move(materials));[/cpp]
Materials is a vector, and the Model uses this vector in its functionality (it is a member). The constructor uses the && qualifier.[/QUOTE]
This is correct.
Just std::move it again when initializing the member in Model, because rvalue-references themselves are lvalues, which means for them to become rvalues again you need to move them.
[QUOTE=DevBug;41728090]rk4[/QUOTE]
The equations i got by googling makes no sense to me as I dont know they purpose. :v
[QUOTE=Fatfatfatty;41731767]The equations i got by googling makes no sense to me as I dont know they purpose. :v[/QUOTE]
[url]http://gafferongames.com/game-physics/integration-basics/[/url]
[QUOTE=dajoh;41731959][url]http://gafferongames.com/game-physics/integration-basics/[/url][/QUOTE]
Um, I think dont understand why I need to predict the position and trajectory of my object. I just want to make it orbit, predictions we can do some other time.
How would you do something like this in c++? This is for an attempt at and component based entity system for a bit of context.
[code]
class Base {...};
class Derive1 : public Base {...};
class Derive2 : public Base {...};
class Derive3 : public Base {...};
class Other {...};
Other::addComponent(Base *item) {
if (!this->items[of type *item]) {
this->items[of type *item] = std::set<*(of type *item)>();
}
this->items[of type *items].insert(item);
}
Other::getItemsOfType(some type) {
return this->items[some type];
}
Other a;
Derive1 *d1 = new Derive1();
Derive1 *d2 = new Derive2();
Derive1 *d3 = new Derive3();
a.addComponent(d1);
a.addComponent(d2);
a.addComponent(d3);
[/code]
Perhaps I'm going about this the wrong way?
[QUOTE=Fatfatfatty;41732084]Um, I think dont understand why I need to predict the position and trajectory of my object. I just want to make it orbit, predictions we can do some other time.[/QUOTE]
You are probably using euler integration at the moment, which looks like this:
[code]velocity += acceleration * dt;
position += velocity * dt;[/code]
This works, but is pretty inaccurate and it only gets worse as dt increases.
Using a better integrator will give you far more accurate orbital calculations, solving your original problem. Your current 'fix' of changing the mass is just covering up a larger issue.
[QUOTE=Chris220;41732138]You are probably using euler integration at the moment, which looks like this:
[code]velocity += acceleration * dt;
position += velocity * dt;[/code]
This works, but is pretty inaccurate and it only gets worse as dt increases.
Using a better integrator will give you far more accurate orbital calculations, solving your original problem. Your current 'fix' of changing the mass is just covering up a larger issue.[/QUOTE]
So this is unacceptable?
[code]public void Update()
{
position += force * S_Global.GameTime1.ElapsedGameTime.Milliseconds;
}
public void Addforce(Vector2 direction)
{
force += direction / mass;
}
[/code]
[QUOTE=Fatfatfatty;41732157]So this is unacceptable?
[code]public void Update()
{
position += force * S_Global.GameTime1.ElapsedGameTime.Milliseconds;
}
public void Addforce(Vector2 direction)
{
force += direction / mass;
}
[/code][/QUOTE]
That would be fine in a game or simulation where physical accuracy does not matter so much, but in this case the loss of accuracy is going to severely impact your ability to produce a correct orbit. If you look into using something like RK4, I think you will find that your simulation's quality will improve drastically.
Hm, this is strange, in this RK4 thingie, position is just represented by one float. I work in two dimensions. How do I implement a Vector2 into it? This is a lot more difficult physics than i have worked with before.
[QUOTE=MayorBee;41732119]How would you do something like this in c++? This is for an attempt at and component based entity system for a bit of context.
[code]
class Base {...};
class Derive1 : public Base {...};
class Derive2 : public Base {...};
class Derive3 : public Base {...};
class Other {...};
Other::addComponent(Base *item) {
if (!this->items[of type *item]) {
this->items[of type *item] = std::set<*(of type *item)>();
}
this->items[of type *items].insert(item);
}
Other::getItemsOfType(some type) {
return this->items[some type];
}
Other a;
Derive1 *d1 = new Derive1();
Derive1 *d2 = new Derive2();
Derive1 *d3 = new Derive3();
a.addComponent(d1);
a.addComponent(d2);
a.addComponent(d3);
[/code]
Perhaps I'm going about this the wrong way?[/QUOTE]
You can use [url=http://en.cppreference.com/w/cpp/types/type_index]type_index[/url] for that.
To speed it up you can use a templated version of addComponent, so you can get the type_index of the component you're adding at compile-time.
[editline]6th August 2013[/editline]
[QUOTE=Fatfatfatty;41732218]Hm, this is strange, in this RK4 thingie, position is just represented by one float. I work in two dimensions. How do I implement a Vector2 into it? This is a lot more difficult physics than i have worked with before.[/QUOTE]
I just skimmed over the articles code, but it seems like it would work just fine with direct translation to N-dimensional linear algebra. Simple component-wise addition and scalar multiplication.
[QUOTE=ZeekyHBomb;41732222]You can use [url=http://en.cppreference.com/w/cpp/types/type_index]type_index[/url] for that.
To speed it up you can use a templated version of addComponent, so you can get the type_index of the component you're adding at compile-time.
[editline]6th August 2013[/editline]
I just skimmed over the articles code, but it seems like it would work just fine with direct translation to N-dimensional linear algebra. Simple component-wise addition and scalar multiplication.[/QUOTE]
I'm going to try to comprehend what that meaned.
[QUOTE=Fatfatfatty;41732084]Um, I think dont understand why I need to predict the position and trajectory of my object. I just want to make it orbit, predictions we can do some other time.[/QUOTE]
Isn't that exactly what you need to know to make an orbit?
[QUOTE=Fatfatfatty;41732353]I'm going to try to comprehend what that meaned.[/QUOTE]
Component-wise addition of two vectors means simply that out[i] = in0[i] + in1[i].
When you visualize that, you put one vector on top of the other. The resulting vector then goes from the beginning of the first vector to the end of the "stacked" vector.
Scalar multiplication is out[i] = scalar * in[i].
When you visualize that, you simply scale the vector by the factor.
[QUOTE=ZeekyHBomb;41732222]I just skimmed over the articles code, but it seems like it would work just fine with direct translation to N-dimensional linear algebra. Simple component-wise addition and scalar multiplication.[/QUOTE]
This is true for all 3D algorithms where no vector is strictly vertical to two existing vectors, because the third scalar in the vector would always be 0 in a 2D problem.
With strictly vertical vectors (think angular momentum/velocity), they become simple scalars and two new cross products have to be defined:
scalar x vector = scalar * vector rotated 90° and
vector x scalar = scalar * vector rotated -90°,
both math-wise, not (necessarily) clock-wise.
[editline]6th August 2013[/editline]
To rotate 90°, switch the components, then invert the first one (= (-y,x)^T),
to rotate -90°, do the same but invert the second one (= (y,-x)^T)
[QUOTE=Fatfatfatty;41732353]I'm going to try to comprehend what that meaned.[/QUOTE]
Essentially what he is saying is that when the original article says you should do some addition on your position variable, you should just do that with your vector equivalents, and when it says you should multiply it by some value, you just multiply your vector by that value instead. Basically it's directly translatable between 1 dimension and 2 or 3 dimensions.
[QUOTE=Tamschi;41732555]This is true for all 3D algorithms where no vector is strictly vertical to two existing vectors, because the third scalar in the vector would always be 0 in a 2D problem.
With strictly vertical vectors (think angular momentum/velocity), they become simple scalars and two new cross products have to be defined:
scalar x vector = scalar * vector rotated 90° and
vector x scalar = scalar * vector rotated -90°,
both math-wise, not (necessarily) clock-wise.
[editline]6th August 2013[/editline]
To rotate 90°, switch the components, then invert the first one (= (-y,x)^T),
to rotate -90°, do the same but invert the second one (= (y,-x)^T)[/QUOTE]
The example code in the article is not for 3D space though. It's for 1D space.
When you have multiplication of two values, and both are 1D-vectors as opposed to scalars, then I'm not sure what kind of multiplication to use, although I'm to lazy to think of an example where this would be the case, though then it would probably be easily apparent.
Luckily though this code only seems to de vector + vector and vector * scalar.
[QUOTE=ZeekyHBomb;41732222]You can use [url=http://en.cppreference.com/w/cpp/types/type_index]type_index[/url] for that.
To speed it up you can use a templated version of addComponent, so you can get the type_index of the component you're adding at compile-time.[/QUOTE]
Not to sure what you mean "templated version of addComponent", I'm not super familiar with templates.
It seems that typeid always returns the base class.
main funciton:
[code]
ComponentHealth *a = new ComponentHealth();
ComponentPosition *b = new ComponentPosition();
e.addComponent(a);
e.addComponent(b);
[/code]
addComponent:
[code]
addComponent(Component *comp) {
std::cout << typeid(*comp).name() << std::endl;
}
[/code]
prints:
class Component
class Component
I'm assuming that's because of the Component *comp, how would i go about getting around this?
[QUOTE=ZeekyHBomb;41732670]The example code in the article is not for 3D space though. It's for 1D space.
When you have multiplication of two values, and both are 1D-vectors as opposed to scalars, then I'm not sure what kind of multiplication to use, although I'm to lazy to think of an example where this would be the case, though then it would probably be easily apparent.
Luckily though this code only seems to de vector + vector and vector * scalar.[/QUOTE]
It's all scalar products, because it's a reduced 3D problem. (The problems that require cross products don't exist in 1D.)
The only possible difficulty I can see is that in 1D taking the length of a vector is (mostly) implicit, so a scalar read can become abs(vector) if the abs() was reduced in the linear problem.
[editline]6th August 2013[/editline]
The article doesn't use that kind of operation though, so it translates 1:1 to vectors.
[QUOTE=MayorBee;41732733]Not to sure what you mean "templated version of addComponent", I'm not super familiar with templates.
It seems that typeid always returns the base class.
main funciton:
[code]
ComponentHealth *a = new ComponentHealth();
ComponentPosition *b = new ComponentPosition();
e.addComponent(a);
e.addComponent(b);
[/code]
addComponent:
[code]
addComponent(Component *comp) {
std::cout << typeid(*comp).name() << std::endl;
}
[/code]
prints:
class Component
class Component
I'm assuming that's because of the Component *comp, how would i go about getting around this?[/QUOTE]
[code]#include <iostream>
#include <typeinfo>
struct Foo
{
virtual ~Foo() = default;
};
struct FooBar : Foo
{
~FooBar() = default;
};
int main()
{
FooBar fb;
Foo *f = &fb;
std::cout << typeid(*f).name() << std::endl;
}[/code]
Works for me. Make sure Component is actually a polymorphic type (i.e. has virtual functions).
As for templated addComponent:
[cpp]template<typename Component>
void Other::addComponent(Component *item) {
const std::type_info type = typeid(Component);
if (!this->items[type]) {
this->items[type] = std::set<Component*>();
}
this->items[type].insert(item);
}
template<typename Component>
const std::set<Component*>& Other::getItemsOfType() {
return this->items[typeid(Component)];
}[/cpp]
And if I may suggest further enhancements:
Use std::set<Component> and use [url=http://en.cppreference.com/w/cpp/container/set/emplace]perfect forwarding[/url] for [url=http://en.cppreference.com/w/cpp/container/set/emplace]std::set::emplace[/url].
If you're okay with Boost, consider boost::flat_set.
Use [url=http://en.cppreference.com/w/cpp/container/set/lower_bound]std::set::lower_bound[/url] to make the lookup in the addComponent-function. With the result you can easily check if the lookup succeeded (iter->first == type) and otherwise you can use it as a hint for insert (or emplace_hint).
[editline]6th August 2013[/editline]
I presume items is a std::map. You could also use std::multimap and return [url=http://en.cppreference.com/w/cpp/container/multimap/equal_range]std::multimap::equal_range[/url] in getItemsOfType if you're not bound on having it store std::sets.
In the code example from [url]http://gafferongames.com/game-physics/integration-basics/[/url] regarding the acceleration function, it takes "float t" but it doesn't utilize t at any point in the equation, why is this?
I integrated it into my code like this, it was copy+paste and doing my damn hardest to try and comprehend all this kind of stuff, but obviously I must have done something hideously wrong fixing the thousands of syntax errors. I suppose C++ and C# arent so easy to convert between as I thought at first :v
[code]physicsStateDerivative evaluate(physicsState initial, float t, float dt, physicsStateDerivative d)
{
physicsState state;
state.Pos.X = initial.Pos.X + d.DX.X*dt;
state.Pos.Y = initial.Pos.Y + d.DX.Y * dt;
state.V.X = initial.V.X + d.DV.X*dt;
state.V.Y = initial.V.Y + d.DV.Y * dt;
physicsStateDerivative output;
output.DX = state.V;
output.DV = acceleration(state, t+dt);
return output;
}
Vector2 acceleration(physicsState state, float t)
{
const float k = 10;
const float b = 1;
return -k * state.Pos - b*state.Pos;
}
void integrate(physicsState state, float t, float dt)
{
physicsStateDerivative a = evaluate(state, t, 0.0f, derivativeState);
physicsStateDerivative b = evaluate(state, t, dt*0.5f, a);
physicsStateDerivative c = evaluate(state, t, dt*0.5f, b);
physicsStateDerivative d = evaluate(state, t, dt, c);
Vector2 dxdt = 1.0f/6.0f * (a.DX + 2.0f*(b.DX + c.DX) + d.DX);
Vector2 dvdt = 1.0f / 6.0f * (a.DX + 2.0f * (b.DV + c.DV) + d.DV);
currentState.Pos = state.Pos + dxdt * dt;
currentState.V = state.V + dvdt * dt;
}
[/code]
My things just dissapear off screen as they move away thousands of miles instantly.
Oh, and the derivative input is never assigned, which results in there not being any derivative change.
Also it calls a function called derivative in the code example, this function is never explained. i just replaced that with the original derivative because I dont know that function.
odd.
I think I might just give up because there's so much stuff that I dont understand of C++ that doesn't work in C#, such as variable names prefixed by a & or variables with a "const" in front of them
It's because your acceleration function (wrongly) doesn't take t into account. 'acceleration' is called with t+dt, so the positions from your state are wrong.
The example simply uses acceleration that is only dependent on state, but leaves the possibility of changing the implementation to something that also depends on time.
Don't C# vectors have overloaded arithmetic operators?
Also your spacing around operator seems completely random :v:
You must adapt acceleration to your world size.
[QUOTE=ZeekyHBomb;41733819]The example simply uses acceleration that is only dependent on state, but leaves the possibility of changing the implementation to something that also depends on time.
Don't C# vectors have overloaded arithmetic operators?
Also your spacing around operator seems completely random :v:
You must adapt acceleration to your world size.[/QUOTE]
I might be a programmer, but this is so much new lingo i have never heard before, arithmetic operators? spacing around operator? Oh god what. I feel so goddamn stupid right now and yet i have 1 year of C++ experience and two years of C#
[QUOTE=Tamschi;41733818]It's because your acceleration function (wrongly) doesn't take t into account. 'acceleration' is called with t+dt, so the positions from your state are wrong.[/QUOTE]
It's the acceleration-method from the example.
It simply calculates a sprind-force, which is only dependent on the current state, i.e. how far it is away from the mounting and it's current velocity.
[editline]6th August 2013[/editline]
[QUOTE=Fatfatfatty;41733841]I might be a programmer, but this is so much new lingo i have never heard before, arithmetic operators? spacing around operator? Oh god what. I feel so goddamn stupid right now and yet i have 1 year of C++ experience and two years of C#[/QUOTE]
Arithmetic operators: operators that do arithmetic, like +, -, *
Spaces around operators: spaces (' ') around operators ("x+x" vs "x + x")
[QUOTE=Tamschi;41733818]It's because your acceleration function (wrongly) doesn't take t into account. 'acceleration' is called with t+dt, so the positions from your state are wrong.[/QUOTE]
t is time, yes and dt is delta time, no? So i send time from gamestart to t and elapsed gametime to dt, i also tried t = 0 all the time, but it still goes bananas, i really dont understand any of this.
[editline]6th August 2013[/editline]
[QUOTE=ZeekyHBomb;41733843]It's the acceleration-method from the example.
It simply calculates a sprint-force, which is only dependent on the current state, i.e. how far it is away from the mounting and it's current velocity.
[editline]6th August 2013[/editline]
Arithmetic operators: operators that do arithmetic, like +, -, *
Spaces around operators: spaces (' ') around operators ("x+x" vs "x + x")[/QUOTE]
Oooh, it was just a fancier word for something I already knew :v
[QUOTE=ZeekyHBomb;41733819]Don't C# vectors have overloaded arithmetic operators?[/QUOTE]
It's a bit problematic with value-type vectors, as operators can't use ref parameters (which is really stupid in my opinion, unless they are inlined in which case the "value call" would be faster once the copy is optimized out).
[editline]6th August 2013[/editline]
[QUOTE=ZeekyHBomb;41733843]It's the acceleration-method from the example.
It simply calculates a sprind-force, which is only dependent on the current state, i.e. how far it is away from the mounting and it's current velocity.[/QUOTE]
That would mean that after dt has passed the acceleration is different from the changed positions though. Or is that irrelevant here?
[editline]6th August 2013[/editline]
[QUOTE=Fatfatfatty;41733859]t is time, yes and dt is delta time, no? So i send time from gamestart to t and elapsed gametime to dt, i also tried t = 0 all the time, but it still goes bananas, i really dont understand any of this.[/QUOTE]
dt must be very small to get enough accuracy, if the elapsed game time is too large you should instead repeatedly evaluate a smaller one.
Sorry, you need to Log In to post a reply to this thread.