
-----------------------------------
CobainMcLean
Fri Jan 20, 2012 1:53 pm

Inaccuracies in round (sind)/(cosd). Trajectory help.
-----------------------------------
Top-Down Trajectory? 


Trajectory off? Drawing line using sind and cosd of rotation?
The problem I'm having is, when determining the point where a bullet will go (Represented by the red line), it is terrible inaccurate. You'll notice that I multiply sind (rotation) by 10000. This makes it MUCH more accurate, but is still not the true trajectory.
Everything in the game is based around the max resolution of your screen, could this be causing the problem?


Describe what you have tried to solve this problem
For one, I've asked my Computer Sciences teacher for help. She doesn't seem to know how to fix this problem either...
I've looked into arcsin/arccos, but can't seem to understand if that will help me?

Also, I know that the program is slightly ineffacant. I'm still working on it, and I'm learning. Any tips are GREATLY appreciated. 

Thanks in advance for any help.  :P 

Turing Version:
4.1

-----------------------------------
DemonWasp
Fri Jan 20, 2012 2:28 pm

RE:Inaccuracies in round (sind)/(cosd). Trajectory help.
-----------------------------------
What do you mean by "terrible inaccurate"?

If you mean the fact that it "jitters" when you're aiming upwards, you should look at this bit of code more carefully:

    if rotation = 360 then
        rotation := 1
    end if


If you mean that rotation moves in large jumps, rather than smoothly, then that has to do with rotating too quickly. Your main loop runs as fast as it can; you should use Time.DelaySinceLast to keep it at a relatively constant rate. You should also use a separate rotation speed and movement speed (you seem to be using the same one for both).

-----------------------------------
CobainMcLean
Fri Jan 20, 2012 3:00 pm

Re: Inaccuracies in round (sind)/(cosd). Trajectory help.
-----------------------------------
Oh, yeah. I never thought that jittering was from that.  Duh :oops: 
However, what I mean, is how as you turn (a and d keys) the red line does not stay centred between the "eyes". 
I know I could use an image, but I need (and am, as we speak) working on bullets that will follow that red lines path (or use the equasion of it)  once fired. 
Thanks for pointing out that stupid error.  :P

-----------------------------------
Insectoid
Fri Jan 20, 2012 3:18 pm

RE:Inaccuracies in round (sind)/(cosd). Trajectory help.
-----------------------------------
You're probably experiencing inaccurate float operations. Floats ('reals' in Turing) are only accurate up to a specified number of significant digits. Since this is a hardware limitation, the only solution is to not use floats (you saw increased accuracy by multiplying by 10000- this increases the accuracy of the value by reducing decimal places). 

Then again, I didn't read your code so I might be completely wrong.

-----------------------------------
Dreadnought
Fri Jan 20, 2012 3:29 pm

Re: Inaccuracies in round (sind)/(cosd). Trajectory help.
-----------------------------------
First, you need to understand what the sine and cosine of an angle are. In a right angle triangle, the sine of an angle is the length of the side opposite the angle over the length of the hypotenuse. The cosine is the length of the side adjacent the angle over the hypotenuse.

This means that given the angle, you can compute the length of the two sides like so.
opposite = sin(angle) * hypotenuse
adjacent = cos(angle) * hypotenuse

Now let's see what you're doing.
floor  (cosd (rotation + 90) * 10000) * Pic.Width (Level) % adjacent
ceil (sind (rotation + 90)* 10000) * Pic.Height (Level) % opposite
I don't know why you use floor for one and ceil for the other but that's not important. What is different in your code from the formulas I wrote?

The hypotenuse doesn't change length. However, Pic.Width(Level) and  Pic.Height(Level) are two different lengths. So you're finding the sides of two different triangles.
That will fix part of the problem.

The other part of the problem, is that you've found the lengths in x and y of the triangle formed by the line of fire of the bullet. However, you forgot to take into account the position of the player on the screen. So the line will change orientation from simple translations of the object, when it should only change from rotation.

So in the end I hope that you see that, in fact, it is not the sin and cos functions causing you trouble.
Hope this helps.

-----------------------------------
DemonWasp
Fri Jan 20, 2012 4:14 pm

RE:Inaccuracies in round (sind)/(cosd). Trajectory help.
-----------------------------------
Dreadnought makes a few good points (edit: I should read more carefully--he actually highlights all of the following. Still, I typed it up, and I won't un-type it). I took another look and you've got several different bugs in that Draw.Line call.

First, your (x2,y2) coordinates in that Draw.Line are wrong. Specifically, your first coordinates (x1,y1) are for the center of your object. Your second coordinates (x2,y2) are for the point several thousand units in the direction your object is facing measured from (0,0), instead of from your object. Try this thought experiment: if your object is at (100,0) and looks straight down, should he be looking at (0, large_number_here) or (100, large_number_here)?

Second, you should put your multiply-by-distance inside your floor() or round() or ceil() call. All of those calls will lose some of the precision available, so do that as late as possible (in particular, try to do any multiplication--especially by numbers above 1--before you cut out the precision). This is why multiplying by 10000 inside the floor() call "improves" accuracy: you are keeping more digits around, so the result seems more accurate.

Third, you should not be multiplying by the width or height of the level. That will produce a kind of ellipsoid (oval) shape instead of the circle you're hoping for.

This snippet works better:

    var x : int := round (Px + Pic.Width (PlayerImage (2)) / 2)  % These are exactly what you had already
    var y : int := round (Py + Pic.Width (PlayerImage (2)) / 2)
    Draw.Line (
        x,
        y,
        x + round (cosd (rotation + 90) * 100 ),  % Note that we add to the coordinates of your object to produce a location relative to it
        y + round (sind (rotation + 90) * 100 ),   % Note that the multiplication by the distance (100) is inside the round() operation.
        brightred
    )
    Time.DelaySinceLast(100)  % If you slow things down, they will be easier to debug. This limits you to drawing and updating 10 times per second (once every 100 milliseconds).


-----------------------------------
CobainMcLean
Sun Jan 22, 2012 6:05 pm

Re: Inaccuracies in round (sind)/(cosd). Trajectory help.
-----------------------------------
Alright, I see what I'm doing wrong. 
The x2 and y2 of the line where off by half of the player image. As both Dreadnought and DemonWasp pointed out. 
So, using the snippet of code offered by DemonWasp, the line works almost perfectly. 

Thanks a bunch guys! :P 

Now, I'm having another problem... Now with creating the bullets.
I have a type which holds a record of X, Y, Xup and Yup. These are the locations of the bullets, and then how much it goes up in the X, and Y axis. 
I then declare a new variable of that record type,as a flexible array. 

[code]
type Bullet :
    record
        X, Y, Type, Xup, Yup : int
    end record
var Bullets : flexible array 1 .. 0 of Bullet
new Bulllets, upper (Bullets) + 1 % Thinking it was because upper of bullets < 1 I added this. I've also tried without.
procedure BulletLogic (New : boolean)
    if New = true and Rate 