Datatypes for physics - c#

I'm currently designing a program that will involve some physics (nothing too fancy, a few balls crashing to each other)
What's the most exact datatype I can use to represent position (without a feeling of discrete jumps) in c#?
Also, what's the smallest ammount of time I can get between t and t+1? One tick?
EDIT: Clarifying: What is the smallest unit of time in C#? [TimeSpan].Tick?

In .Net a decimal will be the most precise datatype that you could use for position. I would just write a class for the position:
public class Position
{
decimal x;
decimal y;
decimal z;
}
As for time, your processor can't give you anything smaller than one tick.
Sounds like an fun project! Good luck!

The Decimal data type although precise might not be the optimum choice depending on what you want to do. Generally Direct3D and GPUs use 32-bit floats, and vectors of 3 (total 96 bits) to represent a position in x,y,z.
This will usually give more than enough precision unless you need to mix both huge scale (planets) and microscopic level (basketballs) in the same "world".
Reasons for not using Decimals could be size (4 x larger), speed (orders of magnitude slower) and no trigonometric functions available (AFAIK).
On Windows, the QueryPerformanceCounter API function will give you the highest resolution clock, and QueryPerformanceFrequency the frequency of the counter. I believe the Stopwatch described in other comments wraps this in a .net class.

Unless you're doing rocket-science, a decimal is WAAAY overkill. And although it might give you more precise positions, it will not necessarily give you more precise (eg) velocities, since it is a fixed-point datatype and therefore is limited to a much smaller range than a float or double.
Use floats, but leave the door open to move up to doubles in case precision turns out to be a problem.

I would use a Vector datatype. Just like in Physics, when you want to model an objects movement, you use vectors. Use a Vector2 or Vector3 class out of the XNA framework or roll your own Vector3 struct to represent the position. Vector2 is for 2D and Vector3 is 3D.
TimeSpan struct or the Stopwatch class will be your best options for calculating change in time. If I had to recommend, I would use Stopwatch.

I think you should be able to get away with the Decimal data type with no problem. It has the most precision available. However, the double data type should be just fine.
Yes, a tick is the smallest I'm aware of (using the System.Diagnostics.Stopwatch class).

I'm not sure I understand your last question, could you please clarify?
Edit:
I might still not understand, but you can use any type you want (for example, doubles) to represent time (if what you actually want is to represent the discretization of time for your physics problem, in which case the tick is irrelevant). For most physics problems, doubles would be sufficient.
The tick is the best precision you can achieve when measuring time with your machine.

For a simulation you're probably better off using a decimal/double (same type as position) for a dimensionless time, then converting it from/to something meaningful on input/output. Otherwise you'll be performing a ton of cast operations when you move things around. You'll get arbitrary precision this way, too, because you can choose the timescale to be as large/small as you want.

Hey Juan, I'd recommend that you use the Vector3 class as suggested by several others since it's easy to use and above all - supports all operations you need (like addition, multiplication, matrix multiply etc...) without the need to implement it yourself.
If you have any doubt about how to proceed - inherit it and at later stage you can always change the inner implementation, or disconnect from vector3.
Also, don't use anything less accurate than float - all processors these days runs fast enough to be more accurate than integers (unless it's meant for mobile, but even there...)
Using less than float you would lose precision very fast and end up with jumpy rotations and translations, especially if you plan to use more than a single matrix/quaternion multiplication.

Related

XNA : How to use double value within Draw() method instead of float to get precise rotation?

I would like to draw an oriented line toward a target depending on a specific angle calculated via tangent which will give a radian result.
As far as i know, to get a precise rotation, i have to use a double value in order to express a correct radian.
However, Spritebatch.Draw requires a float value as rotation:
public void Draw (
Texture2D texture,
Vector2 position,
Nullable<Rectangle> sourceRectangle,
Color color,
**float rotation,**
Vector2 origin,
float scale,
SpriteEffects effects,
float layerDepth
)
If i convert the double value to float, the angle is incorrect and it will miss the target i am expecting to intersect.
How can i draw the correct oriented line based on my double instead of float?
The best case could be to trace the line inside the Update() instead of the Draw() but i think i'm not enough experienced to achieve that with a thing like Vector2.Transform() because i can't visualize what it will do and i can't find a proper noob-oriented explanation.
I don't think you're going to be able to get any more precise than that. You're using XNA, which means you're stuck using XNA's API. There is no overload for Draw that takes a double there. Just float.
Graphics cards don't have great support for doubles anyway. Consider this link: https://msdn.microsoft.com/en-us/library/windows/desktop/bb509646%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
That talks about the different scalar types that HLSL can support. It does list double as an option, but it states that
You cannot use double precision values as inputs and outputs for a stream.
XNA is actually a rather thin wrapper over DirectX, so I wouldn't expect it to support much in the way of doubles. In fact, I'm having a hard time thinking of any game framework that uses double. WPF is the closest I can think of, and that's a UI framework, not a game dev framework.
For the purpose of a video game, it's rather rare that float isn't precise enough for what you're doing. I suspect that there's either a separate, genuine bug that's preventing you from getting things accurate enough (which even double wouldn't save you with), or an entirely different approach that you could take that would get you around it.
I know you already thought of this, but if precision is really the only problem here, you could do the math separately, ahead of time, and then just convert it to a float when you pass it in to the Draw call.

How to detect string when pitch-tracking on electric guitar?

Hi I'm a noob in audio related coding and I'm working in a pitch tracking DLL that I will use to try to create a sort of open-source version of the video-game Rocksmith as a learning experience.
So far I have managed to get the FFT to work so I can detect pitch frequency (Hz) then by using an algorithm and the table below I can manage to determine the octave (2th to 6th) and the note (C to B) for played note.
The next step is to detect the string so I can determine the fret.
I've been thinking about it and in theory I can work with this, I will know when the user is playing the right note but the game could be "Hack" because by just using the Hz the game is not able to detect if a note is played in the right string. For example 5th string + 1th fret = C4 261.63Hz is equals to 6th string + 5th fret = C4 261.63Hz.
The chances of having an user playing a note in the wrong string and getting it right is low, but I think it would be really good to know the string so I can provide to the users some error feedback when they play the wrong string (Like you should go a string up or down).
Do you know what can I do to detect the string? Thanks in advance :)
[edit]
The guitar and strings that we are using affect the timbre so analyzing the timbre seems to not be a easy way of detecting strings:
"Variations in timbre on your guitar are produced by an enormous number of factors from pickup design and position, the natural resonances and damping in your guitar due to the wood used (that's a different sort of timber!) and its construction and shape, the gauge and age of your strings, your playing technique, where you fret and pluck the string, and so on."
This might be a little bit late because the post is one years old. But here's a solution, which I found out after long research for pitch detecting a guitar.
THIS IS WHY FFT DOESN'T WORK :
You cannot use FFT since the result gives you a linear array, and the sound is calculated logarithmically (exponential distance between notes). Plus, FFT gives you an array of bins in which your frequency COULD BE, it doesnt give you the precise result.
THIS IS WHAT I SUGGEST :
Use dywapitchtrack. it's a library that uses a wavelet algorythm, which works directly on your wave instead of calculating large bins like FFT.
description:
The dywapitchtrack is based on a custom-tailored algorithm which is of very high quality:
both very accurate (precision < 0.05 semitones), very low latency (< 23 ms) and
very low error rate. It has been thoroughly tested on human voice.
It can best be described as a dynamic wavelet algorithm (dywa):
DOWNLOAD : https://github.com/inniyah/sndpeek/tree/master/src/dywapitchtrack
USE(C++):
put the .c and .h where you need it and import it in your project
include the header file
//Create a dywapitchtracker Object
dywapitchtracker pitchtracker;
//Initialise the object with this function
dywapitch_inittracking(&pitchtracker);
When your buffer is full (buffer needs to be at 44100 resolution and power of 2 of length, mine is 2048):
//use this function with your buffer
double thePitch = dywapitch_computepitch(&pitchtracker, yourBuffer, 0, 2048);
And voilĂ , thePitch contains precisely what you need. (feel free to ask question if something is unclear)
An simple FFT peak estimator is not a good guitar pitch detector/estimator, due to many potentially strong overtones. There exist more robust pitch estimation algorithms (search stackoverflow and DSP.stackexchange). But if you require the players to pre-characterize each string on their individual instruments, both open and fretted, before starting the game, an FFT fingerprint of those characterizations might be able to differentiate the same note played on different strings on some guitars. The thicker strings will give off slightly different ratios of energy in some of the higher overtones, as well as different amounts of slight inharmonicity.
The other answers seem to suggest a simple pitch detection method. However, it is something you will have to research.
Specifically, compare the overtones of 5th string 1st fret to sixth string 5th fret. that is, only look at 261.63*2, 261.63*3, *4, etc. Also, try looking at 261.63*0.5. Compare the amplitudes of the two signals at these freqs. There might be a pattern that could be detected.

What is the best approach to plot graphs?

I am working on a graphing calculator application, and of course, the main feature of the application is to display graphs.
Right now, this is how my algorithm of plotting graphs works: I divide the drawing canvas in N intervals (where N is defined the application's settings, default value is about 700). For each interval, I evaluate the function for the two ends, and I draw a segment between the two points.
Here are the disadvantages I found to this method:
The precision of the graph isn't great (for example the function sin(tan(x)) )
Rendering gets slow for a higher number of intervals (e.g. N is above 1000). Also, zoom and navigation controls suffer.
So is there a better approach to drawing graphs?
I am programming in C# (WPF), but I think this is irrelevant, because I am looking for an algorithm.
A better approach would be to use adaptive interval sizes. That is, start with relatively coarse intervals, say 20. For each interval, compute the function for the interval ends and the middle. If the middle point is close to the line connecting the two end points, draw a line and you're done with that interval. If not, split the interval in two and repeat with the two smaller intervals.
If the interval gets too small without converging to a line, you've probably found a discontinuity and should not connect the interval endpoints.
You don't need to write your own algorithm if you are plotting some arbitrary functions. Use a graph control from a relevant library, see here and provide the neccessary data (x, y cordinates).
I hope i can help you with this snippet of C++ program which i made few years back using primitive graphics.h ported for mingw compiler. The variable names are pretty much clear.
void func_gen(char expr[100],float precision,int color)
{
float x=-(xres/2)/(float)zoom_factor;
float max_range=-x;
while(x<=max_range)
{
float y;
y = evalu(expr,x); //user defined function which i used to evaluate ann expression
float xcord=xby2+zoom_factor*x+xshift;
float ycord=yby2-zoom_factor*y+yshift;
if(xcord<=xres && xcord>=0 && ycord>=0 && ycord<=yres)
putpixel(xcord,ycord,color);
x=x+precision;
}
}
This method gets pretty slow when i reduce the precision value (which actually increases the precision of the plot :p, sorry for noobness)
I think you should do with DrawPath. That method use an auxiliary structure (a GraphicsPath) optimized just for kind of task as you are coding. edit A small optimization could be to eval the function just at the left point of the segment, and eval at close point just on last segment.

Avoid floating point precision issues

I'm about to create a terrain for a mobile game which allows a huge terrain which is mostly limited by the available hardisk space.
This requires to keep the floating points limited to a "after-point-precision" of 2 numbers.
What is a good approach to keep it at the precision of 2 numbers after the point?
Remember: I'm running on a mobile device, so the method should be fast and easy to use and should be applicable to any arithmetic which is needed for games.
More information
I'm not talking about space( i know how much space a float takes guys, really ), i'm talking about the issue that i loose precision when my floating point is going to have to many numbers after the decimal point.
Using a int would cause that i've to convert the int into a float each frame. I don't know how fast the conversion is but this seems to cost a lot of performance when doing it for a lot of objects. ( Remeber i'm on a mobile device ).
Of course i'm also not talking about the terrain, i'm talking about objects in the terrain! The terrain is a specialized system which actually can hold a terrain size which extends the limits of the floats a lot ( It's even possible to save north america in this system when you have enough disk space, but actually the limits are set to -99km to +99km ).
Edit 2
As usual in games the movement is timebased, means i need to multiply the speed of the object with a modifier given to me by unity, this corrupts my numbers which are limited to 2 numbers after the decimal point.
An interesting way would be to implement this into the movement function:
float result = //multiply force by time
float modulus = result%0.01f;
result -= modulus; //you will do this in any case
if(modulus>=0.005f) {/*round up. if you want it to only round down, remove
the next 2 lines, if you want it to only round up, remove
the conditional statement*/
result+=0.01f; }
I can't think about how to optimize it further, I removed the else statement and have it take away the modulus without condition as it will be done anyway.
Huh, doesn't matter what precision you choose to operate at they still take up the same amount of space. Single or double would make a difference, but the real question you should ask is do you need floating points at all. If you can fit the numbers in an int, do that.

C# double precision issue, how to detect and handle in a safe way

I was looking for satisfactory and safe workaround to my double precision issue specified to this problem:
This program tries to find how many small circle can fit into a large circle. It fills the large circle and then culls those that intersect the large circumference. using this formula:
distance_small_pos_from_center + small_radius < big_radius
All calculations were in double, except for screen output on WinForms which takes int for coords.
The above image shows the result of the culling. You can see that it is not symmetric when it should really be because the constraint is that there must be one small circle exactly in the center. I step through the code and find that this is because some calculations yield, for example,
99.9999999 < 100
This answer C++ double precision and rounding off says we should use all the precision available, but in this case, I had to do a Math.Round(distance_small_pos_from_center + small_radius, 3) using 3 arbitarily.
The result of the culling differs very much without Math.Round. In retrospect, this is one kind of bug that is hard to detect if I had not drawn it out. Maybe I did something wrong, or didn't understand doubles as much as I thought I had.
So, anyone has solutions or tips to avoid this kind of problem?
Sorry for not beeing able to provide a complete answer to your question, but i have no time for that right now. But when you compare floats, compare them with a "tolerance" since a float is not exact.
EDIT: modified with abs() in case you don't know which is big and small, as pointed out by Hans Kesting
Ie, do something like if(abs(big_radius - distance_small_pos_from_center) < epsilon) where epsilon is your tolerance, selected with consideration to how "inexact" the floats will be in the range where you are working..
For more precise information see:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
http://www.cplusplus.com/forum/articles/3638/
Use System.Decimal:
http://msdn.microsoft.com/en-us/library/system.decimal.aspx

Categories