To get 0=+y, 90=+x, ... let's call it the 12o'clock system, and the 0=+x, 90=+y version the right-handed system...

From right-handed to 12:00: theta12 = 90-theta_rh. From 12:00 to right-handed: theta_rh = 90-theta12. ... Use pi/2 if you want to do the same for radians.

As for which to apply where, that really depends on what you're aiming for. If you want to work with 12o'clock values, then put the conversion at the top of any function that uses theta for major calculations. The only question that follows is how you'd reference theta later, which brings us back to the previous issue.]]>

As for x, notice the number of 0s. This is the limitation of floating point arithmetic, aka rounding error. Pi/2 is an irrational number with infinitely many digits. You can't represent all of those in 64 bits. You can't represent all of those in 9000 bits, because 9000 is less than infinity. So you inevitably have

I mean, you have 10 zeros after the decimal point. If you're measuring in meters, that is enough accuracy that you'd need some very expensive equipment to detect the difference. It's still bigger than atoms, but I'm not sure that a paramecium would notice.]]>

if 90 degrees = 1.5707963268 radians, and knowing that position = velocity*DT:

double theta = 1.5707963268;

vector vel((acc.x/M2)*cosine(theta), (acc.y/M2)*sine(theta), grav.z);

This should make the ball travel 90 degrees. That would mean that it would travel strictly on the x axis, and none on y, meaning that Y should remain 0. However, this is what the log shows the travel to be. I've only shown the first 5 entries, but you will see what I mean:

position of ball.x is -0.000000000019894, position of ball.y is 3.8982412815094.

position of ball.x is -0.000000000039591, position of ball.y is 7.75790357589722.

position of ball.x is -0.000000000059289, position of ball.y is 11.6175222396851.

position of ball.x is -0.000000000078986, position of ball.y is 15.4771375656128.

position of ball.x is -0.000000000098684, position of ball.y is 19.3368358612061.

I see two problems here. First of all, the ball is travelling along the Y axis instead of the X one, meaning that it's going straight ahead. Last time I checked, that's not 90 degrees. Second of all, the ball is moving very, very, very slowly along the X axis, but apparently in the wrong direction, as the numbers are negative, which would mean the ball is moving to the left. Again, not 90 degrees. And I know that my math is correct. I doubt very seriously that every website showing the value of 1.5707963268 radians is that mathematically fucked up. And I just verified it with a calculator. So, again, my question is, what...the...fuck?]]>

I have a suspicion that if I made math a class and declared theta there it would work correctly. But I was hoping to avoid doing that. To me, it just makes sense for them to be global. Math is math, global across the board. Specific formulae related to physics are immutable. I shouldn't need a specialized class for this. The only two vectors that make any sense to me being in a class at all are the ones for position of the ball in the ball class, and the position of the player in the player class. Other than that, to me it makes the most logical sense for all other vectors related to physics to be global, and for all specific formulae to be global as well.]]>

I think the main confusion here is over how variables are managed internally. I can try to explain how that should work in this case, but it might take a while.]]>

void move(theta@ T)

but the compiler wasn't pleased. The only global variables I have for the purposes of this test are in the main test script, vectest.bgt:

#include "sound_pool.bgt"

#include "voice.bgt"

#include "math.bgt"

#include "ball.bgt"

#include "clock.bgt"

#include "player.bgt"

#include "logger.bgt"

#include "snapshot.bgt"

Voice speaker;

sound_pool env;

ball B;

player user;

player opponent;

logger test;

bool testing;

clock C(150);

void main()

{

show_game_window("");

init(); //This is simply to return DT correctly.

B.pos.z = 500; ..Giving the ball enough height for testing.

while(true)

{

move(2.5);

//Just different key checks for testing purposes, to make sure values are correct.

if(key_pressed(KEY_D))

speaker.speak(drag.x + ", " + drag.y + ", " + drag.z + ".");

if(key_pressed(KEY_P))

speaker.speak(B.pos.x + ", " + B.pos.y + ", " + B.pos.z + ".");

if(key_pressed(KEY_V))

speaker.speak(vel.x + ", " + vel.y + ", " + vel.z + ".");

if(key_pressed(KEY_F))

speaker.speak(C.frame);

}

}

void move(double theta)

{

B.moving = true;

test.write("test.log", true);

B.pos += vel*DT;

test.add_entry(C.frame);

if(B.pos.z <= 0)

{

env.destroy_all();

B.moving = false;

testing = false;

exit();

}

if(C.frame == 5)

{

B.slot = env.play_2d("sounds/ball.ogg", user.x, user.y, B.pos.x, B.pos.y, false);

C.frame = 0;

}

C.tick();

C.update();

env.update_sound_2d(B.slot, B.pos.x, B.pos.y);

}

As you can see, no theta. in ball.bgt:

class ball

{

float x, y, z;

vector pos(0, 0, 0);

int slot;

//These booleans will be adjusted given the new vector implementation, but for now, they can remain.

bool tossing = false;

bool moving = false;

bool rising = false;

bool choosing = false;

ball()

{

x = 0;

y = 0;

z = 0;

}

ball(float x, float y, float z, int slot)

{

this.x = x;

this.y = y;

this.z = z;

this.slot = slot;

}

Again, no declaration of theta.

In math.bgt:

double CT = 1.2;

double DT;

double theta;

double deg;

float M2 = 0.057;

float x, y, z;

float d;

float roh = 1.151;

float A = 0.0033;

float CD = 0.507;

float FL;

float DX = (CD*roh*A)*power((vel.x/2),2);

float DY = (CD*roh*A)*power((vel.y/2),2);

float DZ = (CD*roh*A)*power((vel.z/2),2);

const double pi = 3.14159265358979;

As you can see, this is the only theta. And since math.bgt is not a class, these variables should be treated as global, just as they are in the main vectest.bgt script. If I change theta in math.bgt, it does change in main. However, if I pass theta to ball, it does not change in main, which means the theta in math.bgt is not being updated correctly. I'm not sure how there is a scope issue, since any variable in math.bgt is global.

So, in the move function, you could access the local theta (theta), the ball's theta (this.theta), or the global theta (::theta), but not a hypothetical theta declared in main, even though main is technically still on the stack.

A quick fix might be to add the following to the move function, near the top. It's not going to resolve the scope issues, but that could take some major reorganizing of your variables, so this is something of a bandaid@:

::theta = theta;

I don't remember if I've ever tried anything like that, but either it will work, or the compiler will have a very self-explanetory complaint.]]>

I wanted to track when theta was changing value, so I did the following:

I added the following lines to main():

test.write("test.log", true);

test.add_entry("Theta in main is " + theta + ".");

In ball:

test.write("test.log", true);

test.add_entry("Theta in move is " + theta + ", T1 is " + T1 + ", and T2 is " + T2 + ".");

And in math, I had to create a function, since it seems that for some reason you can only write to a log file within a function:

void debug()

{

test.write("test.log", true);

test.add_entry("Theta in math is " + theta + ".");

}

This is what the log shows:

Theta in main is 0.

Theta in move is 4.5, T1 is 1, and T2 is 0.

Absolutely nothing, not even 0, in math. Math is not listed at all in the log, and it should be. What this looks like to me is that the original theta, the one in math, which is the only one I declared, isn't changing at all. Evidence of this is in the values of 1 and 0 respectively for T1 and T2. Keep in mind that if theta were truly 4.5, then T1 and T2 would be much different, since T1 = cosine(theta), and T2 = sine(theta). If I were to go into math and change double theta; to double theta = 4.5, then theta is now changed in main, in move it remains 4.5, and now T1 and T2 are:

Theta in main is 4.5.

Theta in move is 4.5, T1 is -0.21079579943078, and T2 is -0.977530117665097.

What that seems to mean is that somehow, a new theta is being declared in void move(double theta)

or the value for theta isn't updating correctly. The thing is, I never declare another theta other than in math: double theta;

In move, I do not declare theta:

void move(double theta)

{

B.moving = true;

test.write("test.log", true);

test.add_entry("Theta in move is " + theta + ", T1 is " + T1 + ", and T2 is " + T2 + ".");

B.pos += vel*DT;

test.add_entry("Ball is now at " + B.pos.x + ", " + B.pos.y + ", " + B.pos.z + ".");

env.update_sound_2d(B.slot, B.pos.x, B.pos.y);

... //more code related to frames and such.

It almost looks like the line void move(double theta) is somehow creating a separate variable named theta. I've never had that happen before. I thought that it was legal to say: void function(data type variable), and it would simply pass the original declared variable value, not create a new one. Which means that when I say:

move(2.6)

the original theta that I declared in math should become 2.6. This is how it has always worked for me in the past. If I passed a variable, i.e., void move(int direction), or void shot(int ShotType), it always updated correctly. This should be no different. And besides, now that I think about it, theoretically, if it is creating another instance of theta, then wouldn't I get a compiler error based on name conflict? I think it's something like: "'theta' is already declared."

This issue makes no damn sense to me.]]>