Ok So, I recently checked out Lazy Foo Tutorials for SDL 1.2, and I read the tutorials.
I want to program a 2 body problem onto the screen. So where the user enters the data for both body, velocity, mass etc, the distance b/w the bodies and such. After that the bodies start
to move on the screen. What I wanted to know was what math would I need to know to program it. I looked into Wikipedia and other sites pertaining to the 2 Body Motion, does the math really need to be as complex as the math that is given on the sites?
http://en.wikipedia.org/wiki/Two-body_problem
Or could I opt to do a simple Formula of Universal Gravitation http://www.regentsprep.org/regents/physics/phys01/unigrav/Image25.gif and then just after every frame just update the two dots on the screen according to the points given by the formula?
Related
I developed a script that calculates the position of N bodies during a gravitational simulation, and I'd like some tips to visualize it. So far, I can either plot the initial conditions, the final position or the trajectories of all bodies, which is not so great. My goal now is "simply" to visualize the movement of all the bodies and/or to plot several figures (one for each time increase) such that, later, it may be possible to do a gif with "animate *.png".
So far I managed to call Gnuplot inside my Fortran code like this:
call system('gnuplot data_test.plt')
Where "data_test.plt" is:
set terminal x11
plot 'teste.dat' pt 5 ps 1
pause 0.1
clear
And "teste.dat" is a file (re-)created at every time increase, which contains the position (x,y) of all the N bodies at that given time.
What's the math behind something like this? C++ perspective.
More examples on this MSDN page here.
UPDATE: Was asked for a more concrete question. What's the math/animation theory for Penner's tweens^? How do you come up with those formulas? What are the math principles they are based on?
Me and math, we are not BFFs! I'm working on a multi-FLOAT value animator for a UI thing I'm writing and I was wondering what's the math from a native C++ programmer's point of view for generating such a trajectory.
Googled and found code but I'm also looking for a bit of theory from a programming perspective... not just code or pure math. I can whip the code I need together from what I found online but I'd like to understand it in the process. Like this site that allows one to experiment with an easing function generator.
I could also use the Windows Animation Manager (and I might if things get bloody), but that operates on a single float. And just animating RGB requires animating each FLOAT by itself. It leads to huge code-bloat... very bad.
If anyone has some hints, I would very much appreciate it. I'm looking mainly for theory from a programming perspective. The end goal is to write a bunch of different animation algorithms that can animate a set of FLOATs from their initial values to their target values in a period of time or speed and such.
The plan is not just to get the code written, but also to understand what goes on behind it. And then maybe get creative with this animations... unless these prove to be some rigid standard math functions.
So think of the requirements for a tweening function.
The function should represent a valid smooth motion between two positions/states. For those who haven't read the relevant section of the book, this means that f should be a continuous and differentiable function such that f(0) == 0 and f(1) == 1; actual motions are constructed using this as a primitive.
"Ease" (in the animation tweening sense) means "derivative is zero"; this gives the effect that the motion starts and/or ends with zero velocity (i.e. a standstill). So "ease-in" means f'(0) == 0 and "ease-out" means f'(1) == 0.
Everything else is based on aesthetic considerations.
Cubic curves (e.g. Bezier/Hermite splines) are popular partly because they let you control both the position and tangent(speed) at both ends of the curve, but also because they are close to the natural shape that a flexible beam adopts if you constrain its position it at a few points. The cubic shape minimises the internal stress of a flexed beam. (Unsurprisingly, these wooden beams are known to boat designers and other drafters as "splines", for this is where we get the word.)
Historically, hand-drawn cartoon animators have always specified their tweens by feel, based on experience. Key animators draw a chart (called a "timing chart"; look this up on your favourite image search engine) on the side of their key drawings, which tell the inbetweeners how the intermediate cels should be timed.
Camera motion (pan, zoom, rotate), however, were a different matter. Layout/animation artists specified the start and the end of the motion (specified using a field chart), the number of frames over which the motion would happen, instructions on easing and anything else the layout/animation team felt important (e.g. if you had to "linger").
The actual motions needed to be calculated; the audience would notice if one frame of a rotation was out even by a couple of hundredths of a degree. Doing these calculations was part of the job of the camera department.
There's a wonderful book called "Basic Animation Stand Techniques" by Brian Salt which dates from back in the days of physical animation cameras, and describes in some detail the sort of thing they had to do, and to what extent. I recommend it if you're at all interested in this stuff.
Math is math is math.
A good tutorial on Riemann Sum will demonstrate the concept.
In fundamental programming, you have a math equation that generates a Y value (height) for a given X (time). Periodically, like once a second for example, you plug in a new X (time) value and get the height back.
The more often you evaluate this function, the better the resolution (this is where the diagrams of a Riemann sum and calculus come in). The best you will get is an approximation to the curve that looks like stair steps.
In embedded systems, there is not a lot of resources to evaluate a function like this very frequently. The curve can be approximated using line segments. The more line segments, the better the approximation (improves accuracy). So one method is to break up the curve into line segments. For a given x, use the appropriate linear formula for the line. Evaluation of a line usually takes less resources than evaluating a higher degree equation.
Your curves are usually generated from equations of Physics. So not only do you need to improve on Math, you should also improve on Physics.
Otherwise you can search the web for libraries that handle trajectories.
As we traverse closer to the hardware, a timer can be used to call a method that evaluates the trajectory function for the given X. The timer helps produce a more accurate time value.
Search the web for "curve fit algorithm", "Bresenham algorithm", "graphics collision detection algorithms"
I'm currently trying to solve a problem regarding the display of an arm avatar.
I'm using a 3D tracker that's sending me coordinates and angles through my serial port. It works quite fine as long as I only want to show a "hand" or a block of wood in its place in 3D space.
The problem is: When I want to draw an entire arm (lets say the wrist is "stiff"), so the only degree of freedom is the elbow), I'm using the given coordinates (to which I've gltranslatef'd and glmultmatrix'd), but I want to draw another quad primitive with 2 vertices that are relative to the tracker coordinates (part of the "elbow") and 2 vertices that are always fixed next to the camera (part of the "shoulder"). However, I can't get out of my translated coordinate system.
Is my question clear?
My code is something like
cubeStretch = 0.15;
computeRotationMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(handX, handY, handZ);
glMultMatrixf(*rotationMatrix);
glBegin(GL_QUADS);
/*some vertices for the "block of wood"*/
/*then a vertex which is relative to handX-handZ*/
glVertex3f(-cubeStretch, -cubeStretch+0.1, 5+cubeStretch);
/*and here I want to go back to the origin*/
gltranslatef(-handX, -handY, -handZ);
/*so the next vertex should preferably be next to the camera; the shoulder, so to say*/
glVertex3f(+0.5,-0.5,+0.5);
I already know the last three line don't work, it's just one of the ways I've tried.
I realize it might be hard to understand what I'm trying to do. Anyone got any idea on how to get back to the "un-gltranslatef'd" coordinate origin?
(I'd rather avoid having to implement a whole bone/joint system for this.)
Edit:https://imagizer.imageshack.us/v2/699x439q90/202/uefw.png
In the picture you can see what I have so far. As you can see, the emphasis so far has not been on beauty, but rather on using the tracker coordinates to correctly display something on the screen.
The white cubes are target points which turn red when the arm avatar "touches" them ("arm avatar" used here as a word for the hideous brown contraption to the right, but I think you know what I mean). I now want to have a connection from the back end of the "lower arm" (the broad end of the avatar is supposed to be the hand) to just the right of the screen. Maybe it's clearer now?
a) The fixed function stack is deprecated and you shouldn't use it. Use a proper matrix math library (like GLM), make copies of the branching nodes in your transformation hierarchy so that you can use those as starting point for different branches.
b) You can reset the matrix state to identity at any time using glLoadIdentity. Using glPushMatrix and glPopMatrix you can create a stack. You know how stacks work, do you? Pushing makes a copy and adds it to the top, all following operations happen on that. Poping removes the element at the top and gives you back the state it was in before the previous push.
Update
Regarding transformation trees you may be interested in the following:
https://stackoverflow.com/a/8953078/524368
https://stackoverflow.com/a/15566740/524368
(I'd rather avoid having to implement a whole bone/joint system for this.)
It's actually the most easy way to do this. In terms of fixed function OpenGL a bone-joint is just a combination of glTranslate(…); glRotate(…).
I'm revising for an OpenGL exam and keep coming across this question on past papers. It's not something I've been taught and I was wondering if anyone could set me off in the right direction.
Sorry I haven't added what I have so far, there's not much because I don't really understand the question either.
"You wish to create a simple animation that shows a small red sphere shrinking and expanding. Specifically the radius oscillates sinusoidally between 0.3 and 0.5 in magnitude.
(i) Discuss the role of the glutIdleFunc in the animation.
(ii) Write the display method that performs the above animation;
assume the radius vector R is of type double and is declared with
global scope."
The glutIdleFunc documentation could set you off in a direction. Notice how it does calculations in the background, so a possible answer could be discussing how the animation behaves by setting or not setting (or simply leaving empty) that particular callback, respectively.
If you are allowed to use glutSolidSphere or glutWiredSphere the display method could be quite simple if you know the basics of OpenGL (assuming you've studied and attended class :). But if you have to use OpenGL 3.3 or 4.0+ you will probably have to think about coming up with an algorithm to first generate the vertices of the sphere (simpler) then the indices of the vertices (little bit trickier). There are numerous examples on the Internet and StackOverflow on how to do that, I do believe.
Good luck on your exam!
I just want to do a simple animation (for example in C++ using OpenGL) of some moving object - let's say simple horizontal movement of a square from left to right.
In OpenGL, I can use "double-buffering" method and let's say a user (running my application with the animation) have turned "vertical sync" on - so I can call some function every time when a monitor refreshes itself (I can achieve that for example using Qt toolkit and its function "swapBuffers").
So, I think, the "smoothest" animation that I can achieve, is to "move the square by for example 1 pixel (can be other values) every time monitor refreshes", so at each "frame" the square is 1 pixel further - "I HAVE TESTED THIS, AND IT SURELY WORKS SMOOTHLY".
But the problem arises when I want to have "separate" thread for "game logic" (moving the square by 1 pixel to the right) and for "animation" (displaying current position of the square on the screen). Because let's say the game logic thread is a while loop where I move the square by 1 pixel and then "sleep" the thread for some time, for example 10 milliseconds, and my monitor refreshes for example every 16 milliseconds - the movement of the square "won't be 100% smooth" because sometimes the monitor will refresh two times where the square moves by only by 1 pixel and not by 2 pixels (because there two "different" frequencies of monitor and game logic thread) - and the movement will look "little jerky".
So, logically, I could stay with the first super smooth method, but, it cannot be used in for example "multiplayer" (for example "server-client") games - because different computers have different monitor frequencies (so I should use different threads for game logic (on the server) and for animation (on the clients) ).
So my question is:
Is there some method, using different threads for game logic and animation, which do "100% smooth" animation of some moving object and if some exists, please describe it here, or when I just had some "more complex scene to render", I just would not see that "little jerky movement" which I see now, when I move some simple square horizontally, and I deeply concentrate on it :) ?
Well, this is actually typical separate game-loop behavior. You manage all you physics (movement) related actions in one thread, letting the render thread to do its work. This is actually desirable.
Don´t forget this way of implementation of game loop is to have maximum available frame rate while preserving constant physics speed. At higher FPS, you can not see this effect by any chance, if there is not any other code related problem. Some hooking between framerate and physics for example.
If you want to achieve what you describe as perfect smoothness, you could synchronize your physics engine with VSync. Simply do all your physics BEFORE refresh kicks in, than wait for another.
But this all applies to constant speed objects. If you have object with dynamic speed, you can never know when to draw it to be "in sync". Same problem arises then you want multiple object with different constant speeds.
Also, this is NOT what you want in complex scenes. The whole idea of V-sync is to limit screen tearing effect. You should definitely NOT hook your physics or rendering code to display refresh rate. You want you physics code to run independent of users display refresh rate. This could be REAL pain in multiplayer games for example. For start, look at this page: How A Game Loop Works
EDIT:
I say your vision of perfect smoothness is unrealistic. You can mask it using techniques Kevin wrote. But you will always struggle with HW limits as refresh rate, or display pixelation. For example, you have window of 640x480 px. Now, you want your object to move horizontally. You can move your object by vector heading towards bottom right corner, BUT you must increment object coordinates by float number (640/480). But in rendering, you go to integers. So your object moves jagged. No way around this. In small speed, you can notice it. You can blur it, or make it move faster, but never get rid of it...
Allow your object to move by fractions of a pixel. In OpenGL, this can be done for your example of a square by drawing the square onto a texture (i.e. a one-pixel or larger border), rather than letting it be just the polygon edge. If you are rendering 2D sprite graphics, then you get this pretty much automatically (but if you have 1:1 pixel art it will be blurred/sharp/blurred as it crosses pixel boundaries).
Smooth (antialias) the polygon edge (GL_POLYGON_SMOOTH). The problem with this technique is that it does not work with Z-buffer-based rendering since it causes transparency, but if you are doing a 2D scene you can make sure to always draw back-to-front.
Enable multisample/supersample antialiasing, which is more expensive but doesn't have the above problem.
Make your object have a sufficiently animated appearance that the pixel shifts aren't easy to notice because there's much more going on at that edge (i.e. it is itself moving in place at much more than 1 pixel/frame).
Make your game sufficiently complex and engrossing that players are distracted from looking at the pixels. :)