I'm not sure what you mean? You can make multiple functions with the same name, so long as the arguments are different, but I don't think that's what you're asking about?

### #27 2017-08-21 16:28:28

Ok, so I have basically completely rewritten my ball class. Not everything is completed, but I've done a lot of research and read a lot of things in the very few spare hours I have in the evenings, and I've tried to make this as realistic as possible. So before I go any further, I'd really like to know exactly which parts that I have so far that are correct, which parts are wrong, and which parts are just beyond totally fucked up, lol. For the parts that are wrong or fucked up, let me know why, and the best way to fix it. So, with all of that being said, here goes:

class ball

{

float x, y, z;

float IG;

float roh;

float A;

float cd;

float FL;

int slot;

ball()

{

vector position;

vector NetF; //force

vector vel; //final velocity

vector acc; //acceleration

vector l1; //current location of ball

vector l2; //location 2, where the ball comes to rest;

vector c; //the court surface

vector d; //distance

}

ball(float x, float y, float z, float IG, float roh, float a, float cd, float FL, int slot)

{

this.x = x;

this.y = y;

this.z = z;

this.IG = IG;

this.roh = roh;

this.A = A;

this.cd = cd;

this.FL = FL;

this.slot = slot;

vector position(0, 0, 0);

vector NetF(0, 0, 0);

vector vel(0, 0, 0);

vector acc(0, 0, 0);

vector l1(0, 0, 0);

vector l2(0, 0, 0);

vector c(0, 0, 0);

vector d(0, 0, 0);

}

//get distance between two vectors

float GetDistance([email protected] V1, [email protected] V2)

{

v.x = v1.x - v2.x;

v.y = v1.y - v2.y;

v.z = v1.z - v2.z;

return d = square_root(power(v.x,2)+power(v.y,2)+power(v.z,2));

}

//calculate initial gravitational force given altitude

float IGForce()

{

float M1 = 5.972*1024; //mass of the earth

float M2 = 0.057; //mass of the ball

float G = (6.6742*power(10, -11)*M1*M2)/(power(d.z,2));

float gtv = 9.81;

if (IG >= GTV)

return;

else if(IG < GTV)

{

return d = GetDistance(L1, C)

return IG = (G*M1*M2)/power(d,2);

}

}

//calculate drag and lift forces

float GetDL()

{

float CD = 0.507; //drag coefficient

float CL = 0.6; //lift coefficient

roh = 1.151; //air density

A = 0.0033; //projected area of the ball

return float drag = CD*A*0.5*roh*power(vel,2);

return float lift = FL*A*0.5*roh*power(vel,2);

}

//calculate impulse and momentum

float ImpF()

{

return float imp = NetF*DT;

return float mom = M2*vel;

}

//calculate net force

{

NetF((strength*CT)+imp+lift-drag-IG)*cos(theta), (strength*CT)+imp+lift-drag-IG)*sin(theta), -IG*sin(theta));

acc = NetF/M2;

}

void move(double DT)

{

vel += pos*DT;

pos += vel*DT;

}

...

I look forward to your reply. Thanks.

JLove

### #28 2017-08-22 20:53:18

In your constructors, you define several vectors, but they don't exist outside of the constructors, so they are immediately destroyed.

That is a lot of detail . I don't know enough about drag/lift to comment on that part.

It seems otherwise reasonable, but that ultimately will be decided based on how it performs.

### #29 2017-08-23 03:25:20 (edited by JLove 2017-08-23 03:28:05)

So what do I need to do with my vectors? In other words, where do I need to create them so that they don't get destroyed? I haven't seen anything else in my constructor get destroyed.

Also, look at this:

float GetDistance([email protected] V1, [email protected] V2)

{

v.x = v1.x - v2.x;

v.y = v1.y - v2.y;

v.z = v1.z - v2.z;

return d = square_root(power(v.x,2)+power(v.y,2)+power(v.z,2));

}

The goal that I am trying to accomplish here, is that I want to take any two vectors I have and get the distance. In other words, I want to be able to call that function and put any two vectors I have as arguments. i.e., GetDistance(L1, L2), or GetDistance(L1, C). I don't want to have to create a separate function for each distance that I want to check. Usually, the best way to do that is to use handles, I think. I did something like that in another function:

void TRestart([email protected] t)

{

t.restart();

}

That way, I can call that from anywhere, with any timer I please: I.e., TRestart(timer A), TPause(timer B), etc. So, that is why I said here:

float GetDistance([email protected] V1, [email protected] V2)

Theoretically, that way I could just plug any two vectors I please into that function call to get the distance between them. However, the compiler gives the following message:

On line: 49 (25)

Line: float GetDistance([email protected] V1, [email protected] V2)

Error: Object handle is not supported for this type

So since I can't use handles, which doesn't make any sense to me, how should I go about it?

One more thing: Did I do the NetForce vector correctly?

{

NetF((strength*CT)+imp+lift-drag-IG)*cos(theta), (strength*CT)+imp+lift-drag-IG)*sin(theta), -IG*sin(theta));

acc = NetF/M2;

}

Adding all of the forces gives the net force...and forces are vectors. So, is that the right way to do it so that x, y, and z all get the correct values and the correct direction? Thanks.

JLove

### #30 2017-08-23 07:09:23

Vectors are weird, handle-wise. You can safely ignore the @ for vector functions, although I don't know exactly what would happen if you try to have a function modify a variable sent as a parameter.

The only other thing you could do differently in the distance function is to cram everything into one statement, which is less clear mathematically, but reduces the function to a single line: return (v1-v2).length();

The only thing about the net force that throws me off is the z component, since using sine(theta) there seems out of place.

### #31 2017-08-23 09:08:43

The reason I used sine(theta) with the z component is that I assume that a ball doesn't just drop like a stone, it comes down while still moving forward, so I wasn't sure whether I needed the direction of z to match the others.

And I'm concerned about my vectors being destroyed. How do you know they're getting destroyed? How do I fix it? None of my other variables seem to be lost. I declared other variables in the constructor, then used them in several functions, I.e., roh, CD, CL, etc. I assumed vectors would work the same way. In my constructor I say vector FNet(0, 0, 0), to assign it an initial value, and then assign its true values in the function when I say: NetF((strength*CT)+imp+lift-drag-IG)*cos(theta), (strength*CT)+imp+lift-drag-IG)*sin(theta), -IG*sin(theta));. But that won't do anything if it's being destroyed. So what did I do wrong, and how do I fix it? Thanks.

JLove

### #32 2017-08-24 22:58:47 (edited by JLove 2017-08-24 23:11:00)

Ok, I think I've got it so that my vectors are not being destroyed, because now I'm getting different errors from the compiler. Let's take them in order. Relevant code:

float GetDistance(vector v1, vector v2)

{

vector v;//this holds the values from the other vectors.

v.x = v1.x - v2.x;

v.y = v1.y - v2.y;

v.z = v1.z - v2.z;

//Now, give the result to the distance vector

return d = square_root(power(v.x,2)+power(v.y,2)+power(v.z,2));

}

The compiler says:

Information: Compiling float ball::GetDistance(vector, vector)

On line: 47 (12)

Line: return d = square_root(power(v.x,2)+power(v.y,2)+power(v.z,2));

Error: Can't implicitly convert from 'double' to 'const vector&'.

So, I tried removing the distance as a vector completely, and just declaring D as a double, since it was trying to convert from a double. You'd think that would make sense, since a double is apparently what it wanted there. and it no longer gave me that error, but what it did do was caused this error to come up in the very next function, before the first line of code was even executed:

Information: Compiling float ball::IGForce()

On line: 52 (1)

Line: {

Error: Not all paths return a value

That { is the first of the function. Code just after the distance function ends:

//calculate initial gravitational force given altitude

float IGForce()

{

float M1 = 5.972*1024; //mass of the earth

...

But it's not even getting to the line of code that declares M1. Which must mean that for whatever reason it is not pleased that I removed the distance vector d and substituted it with a double instead. return d = square_root(power(v.x,2)+power(v.y,2)+power(v.z,2));

That formula is the correct one for distance, I double checked that. It obviously did not want me to use a vector, because of the, "Error: Can't implicitly convert from 'double' to 'const vector&'.", message. I tried using a double there, since then it wouldn't have to convert anything, and it still was not pleased. I got the, "not all paths return a value," message, even though I gave it the double that it obviously wanted, no conversion required. Then, I tried making d a float, then an int, just to see, and got the same "not all paths..." message, no matter what type I used. So what the hell? If it can't convert to a vector from a double, but it doesn't want a double, which makes no sense, since that would mean that there would be no conversion required, and I can't use any other type, then what the fuck does it want? It's obvious to me that the not all paths error is coming from the formula, because until I removed D as a vector, it was fine. But I can't have D as a vector apparently. Just like a damn woman...can't decide what the hell she wants. how do I fix it?

### #33 2017-08-25 01:27:42

The "not all paths return a value" error should have appeared along with the "no conversion availible" error, since they are apparently unrelated.

The function is supposed to return a float, but there is a way to get to the end without anything being returned. It can't point to a line because the error is that there is a missing line, so it points to the beginning of the function in question.

Actually, looking at the IGForce function again, all of the returns are weird. I don't know how BGT deals with returning and assigning in one statement (I've seen something like that work in C, though, so maybe it works?), but you have one empty return, and your else has two returns in sequence.

In this case, where you seem to be calculating the force of gravity, I'm a little lost about what the if is for. Also, every physics class I've taken recommends just rounding to 9.81 as the acceleration due to gravity, for any human-scale objects, since, when compared to the mass of the Earth, the mass of anything less than the moon is a rounding error. (I think we were once even told we could ignore the mass of the Earth when calculating for the Earth/sun gravity, the difference is so great.) So, unless you want to reuse the ball class for simulating the moon falling on the Earth, this might be overkill. (I don't mean in the since that it's too complex to notice; I mean in the since that the difference will be drowned out by floatingpoint rounding errors, because you only have 32-64 bits).

### #34 2017-08-27 04:07:14

Two questions: First, exactly what type of integers are stored in vectors? I.E., int, uint, float, double, or what? Given that velocity is a vector, consider the following formula:

Drag equals the drag coefficient times the density times the area times half the velocity squared.

So, keeping in mind that velocity is a vector, consider the following line of code, wher CD is the drag coefficient, A, is the area, and rho is the air density:

return drag = CD*roh*a*power((vel/2),2);

That is the formula exactly as it is stated above. The compiler says:

On line: 72 (24)

Line: return drag = CD*roh*A*power((vel/2),2);

Error: No matching signatures to 'power(vector, const int)'

So then I changed it slightly:

return drag = CD*A*roh*power((vel.x/2),2);

And got the error:

On line: 72 (15)

Line: return drag = CD*roh*A*power((vel.x/2),2);

Error: Can't implicitly convert from 'double' to 'const vector&'.

Except this time I asked for a specific integer from the vector, not the entire thing at once. In other words, vel.x should be a number. I wouldn't think it would be a problem to use a single number.

So my question is, if I can't use the vector, and I can't use single components of the vector, how am I supposed to perform mathematical calculations like power, square_root, etc. on vectors?

Second question: Is it possible to create a function that returns a vector? Technically, any force is a vector. That would include drag. So shouldn't I actually want a vector? Something like:

vector DL()

{

vector drag;

float CD = 0.507;

float CL = 0.650;

roh = 1.151;

A = 0.0033;

//return the vector with direction:

return vector drag(CD*roh*A*power((vel.x/2),2)*cosine(-theta), CD*roh*A*power((vel.y/2),2)*sine(-theta), -z);

Z is obviously gravity, so irrelevant here.

### #35 2017-08-27 05:16:55

You can return vectors—you can return just about anything—but the power function only works with individual numbers. (You could write a version that takes a vector, I suppose...)

The reason for the error after you tried just using the x component is because power returns a double, but drag is a vector. You can use the first version if you write a power function to work with vectors; otherwise, you'd need to set the drag components individually. The vector object overloads the arithmetic operators, but it's still a distinct type where functions are concerned.

So something like:

vector power(vector v, double exponent) {

vector ret (power(v.x, exponent), power(v.y, exponent), power(v.z, exponent));

return ret;

}

... as a global function. Come to think of it, something like this should probably go in my math file.

I don't actually remember if the power function works with fractional exponents. If it does, you can just use 0.5 for square roots and be done with the one.

### #36 2017-08-27 07:35:17

The reason I asked whether it was possible to return a vector is that when I try doing that, I get the "not all paths return a value" error. Look at this:

vector DL()

{

float CD = 0.507;

float CL = 0.650;

roh = 1.151;

A = 0.0033;

vector drag(CD*roh*A*power((vel.x/2),2)*cosine(-theta), CD*roh*A*power((vel.y/2),2)*sine(-theta), z);

The compiler says:

On line: 66 (1)

Information: Compiling vector ball::DL()

On line: 67 (1)

Line: {

Error: Not all paths return a value

What the fuck unaccounted for path is it seeing before the vector? If I take this one line at a time, I see nowhere that a value can get returned that isn't listed here.

float CD = 0.507;

That value is etched in stone.

float CL = 0.650;

Also etched in stone.

roh = 1.151;

More stone.

A = 0.0033;

Still more stone.

vector drag(CD*roh*A*power((vel.x/2),2)*cosine(-theta),

There's the x component of the vector

CD*roh*A*power((vel.y/2),2)*sine(-theta),

There's the y component, and then I use z for gravity. So where the fuck is the extra path that it's seeing, the one that supposedly doesn't return a value?? All of the numbers look accounted for.

### #37 2017-08-27 08:10:40

Ok, continuation of last post. For some reason, adding one line of code seems to have fixed it:

vector DL()

{

float CD = 0.507;

float CL = 0.650;

roh = 1.151;

A = 0.0033;

vector drag(CD*roh*A*power((vel.x/2),2)*cosine(-theta), CD*roh*A*power((vel.y/2),2)*sine(-theta), z);

return drag;

}

For some reason, now I don't get the "not all paths return a value" message anymore. The only thing I added was "return drag;". I don't know if it's truly fixed, but at least that error is gone. Explain please.

### #38 2017-08-27 17:14:58

The return value is independent of any changes the function makes; if the function is declared as anything but void, it must return something of that type via the return statement. If the function is changing global or variables or class properties, it might not need to return anything but void. If you want to get a value out of the function, such as how we were using the power function earlier, that's when you need a return type.

So for example:

int total=0; //This is a global variable.

void increase(int a) {

total += a;

}

int sum(int a, int b) {

return a+b;

}

Both functions add one number to another. The first one only changes an existing variable, so it's type is void and it returns nothing. The second puts the result in a new variable, which must be returned to be used, so its type is int and it ends in a return statement.

The not all paths error can happen if you have a more complicated function with multiple paths. For example, the following will result in a compilation error:

double atan2(double x, double y) {

if (x==0) {

if(y<0) return -3.14/2;

else return 3.14/2;

}

double theta=arc_tangent(y/x);

if(y<0) return theta+3.14;

}

Since there is no return statement when y>=0, the compiler will tell you that not all paths return a value. This can be corrected by adding the line

return theta;

to the end of the function.

hth

### #39 2017-08-27 22:33:26 (edited by JLove 2017-08-27 22:44:40)

So basically, if I understand correctly, this line:

vector drag(CD*roh*A*power((vel.x/2),2)*cosine(-theta), CD*roh*A*power((vel.y/2),2)*sine(-theta), z);

didn't actually return the vector. it just set the values. This line:

return drag;

actually returned the vector. Is that correct?

Ok, now I'm getting a different error. Force is a vector. Adding all of the force vectors together make the total, or net, force. That net force determines what the acceleration, and thereby, the velocity will be. Look at the following lines of code:

vector NetF((strength*CT)+lift-drag*cosine(theta), (strength*CT)+lift-drag*sine(theta), -IG);

The acceleration formula is acceleration = total, or net force, divided by the mass of the ball. So:

acc = NetF/M2;

The compiler says:

On line: 86 (65)

Line: vector NetF((strength*CT)+lift-drag*cosine(theta), (strength*CT)+lift-drag*sine(theta), -IG);

Error: No conversion from 'vector' to math type available.

There are several of those. They appear to coincide with the + signs where I'm adding forces. But I should be able to add vectors, or do I need to write a function to add them like I have to for performing exponent calculations on them? I cannot believe that some of these math calcs were not added into the vector object so that we could do math without all of this fucking drama. Especially given that when you use vectors, it's expected, it's a fucking guarantee, that math is damn well gonna occur. Vector add, vector sub, vector mult, vector divide, vector power, vector normalize, cross product, and dot product should be fucking intrinsic, built into the damn thing. Not to mention the fact that we should be able to use handles. It'd make things a fuck load easier.

then, further down:

On line: 87 (12)

Line: acc = NetF/M2;

Error: 'M2' is not declared

But, that's bullshit. Yes, it is. Remember above, in the function where I calculate grav force:

float M1 = 5.972*1024; //mass of the earth

float M2 = 0.057; //mass of the ball

Unless I have to redeclare the M2 variable every time I need it? Really?

### #40 2017-08-27 23:02:25

Regarding m2: remember earlier when I mentioned the vectors being declared in the constructors being a problem? Basically, if you create a variable inside a function, the variable is destroyed when the function ends, unless it's the returned value. You can either declare m2 as a class property, or make a global constant. I don't remember if the BGT manual has a section on scope, but that's the subject that would cover this problem.

About netf... it's kinda hard to keep track of, since I'm reading on mobile, but I think the trouble is that you're mixing up when to use the vector, and when to reference its components. There are effectively 3 ways to define a vector: use one of the constructors (vector(x, y), or vector(x, y, z)), assign it the value of another vector (this is what happens when you say vectorA = vectorB + (vectorC / 2)), and getting it from a function (v = get_velocity();). What it looks like is that you're mixing the first two. If you need to specify the x y and z individually, you should probably use the constructor.

### #41 2017-08-28 00:53:20

Ok, so if I can legally assign a vector it's value by adding two or more other vectors, then to get total, or net, force, I should be able to say something like:

vector NetF()

{

vector NetF = (imp+lift-drag-grav);

vector acc = (NetF/m2);

}

So I tried it, and this is what the compiler says:

On line: 90 (19)

Line: vector NetF = (imp+lift-drag-grav);

Error: Invalid operation on method

The character at (19) is a plus sign. But I thought we just established that it is perfectly okay to say vector A = vector B + vector C? Which is all I did here. Vector NetForce equals vector imp plus vector lift minus vector drag minus vector grav. Where's the issue?

### #42 2017-08-28 14:42:11

I'd have to go back and check, but that error makes it sound like a variable and a function have the same name.

### #43 2017-08-29 16:15:26 (edited by JLove 2017-08-29 16:18:28)

Update, with a couple of questions: So, I got all of the compiler errors fixed, but when I ran the test, all of my values stayed at 0, even with all of the formulae. I was not pleased. I tried all sorts of ways to fix it. I moved all of my vectors from my bottom constructor to my top one, still no luck. I even tried creating functions to return the vectors, which should have made them not get destroyed, since I didn't think a returned value was destroyed after function completed. Still no luck. Finally, I got pissed and tried one last option. I moved everything over to my math.bgt script. Now, for some reason, everything works correctly. My question is, is it better in terms of efficiency to put the vectors and associated functions back into the ball object, or is it better to leave them in math, and just have the ball functions for movement and updating position? If it's better to return them to ball, then I need to know exactly where to put them so that they're not destroyed, and so that functions with equations actually work on the associated vector correctly. I don't understand why they were being destroyed anyway, since none of my other variables were ever destroyed. It seemed to only apply to the vectors. One other question. Either I'm confused, or I'm a fucking moron (which isn't beyond the realm of possibility, lol). I thought that vectors could be added together without defining each component separately. For example:

vector pillow(3, 3, 3);

vector willow(5, 9, 15);

And then, I thought that you could just do this:

vector billow = pillow+willow;

I didn't think that I had to do:

vector billow.x = pillow.x+willow.x;

vector billow.y = pillow.y+willow.y;

vector billow.z = vector pillow.z+willow.z;

Is that incorrect? Do I have to perform calculations on each separate component? I ask because I have the following. This is merely for testing purposes, the values are not relevant to the actual code:

double strength = 3;

double CT = 1.2;

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);

vector drag(DX, DY, DZ);

vector lift(5, 1, 3);

vector imp = (strength*CT)+lift-drag;

So, I've basically said that the vector imp is (strength*CT)...I want that done first...and then added to the vector lift, minus the vector drag. I thought I could do that? But when I do that, the compiler says:

On line: 21 (27)

Line: vector imp = (strength*CT)+lift-drag;

Error: No conversion from 'vector&' to math type

Now, if I did each component separately, it would work. But again, I thought that operations could be performed on two vectors without having to break them down that way.

### #44 2017-08-29 16:38:25

It is probably better to keep the vector functions separate, and just let the ball class handle movement and updating position.

Regarding your second question: yes, you can add vectors in that way. The problem is that you try to add (strength*CT) to a vector, and strength*CT is a double. If you just tried imp=lift-drag, you would not get any errors. I'm guessing you meant to apply strength*CT to a vector, then add that to lift-drag? Because that would work, and from the context, that seems like what you meant.

### #45 2017-08-29 18:04:11

Yeah. Basically, strength*CT will be used to calculate the force of the shot, to determine initial velocity. So if, at the beginning before the ball is struck, vector vel = (0, 0, 0), then (strength*CT) will determine how much acceleration to impart. So velocity might go from (0, 0, 0) to say (3, 3, -grav). Lift is there to determine the amount of spin to place on the ball. (Strength*CT) gets added to lift, and drag get's subtracted from that, because NetForce is acquired by adding all forces together. That includes everything: Strength of shot, lift, drag, gravity, anything that can affect the trajectory of the ball, and, from what I have read, each force itself is a vector. Total net force is also a vector.

That brings me to the next question. Each vector has to have a direction. Do I have to assign that direction to each component separately, I.e.:

vector pillow(3*cosine(theta), 3*sine(theta), -grav.z);

vector willow(5*cosine(theta), 9sine(theta), -grav.z);

vector billow = pillow+willow;

or can I do it for the entire vector? I know this will most likely be wrong, but you'll get the point. Something like:

vector pillow(3, 3, 3);

vector willow(5, 9, 15);

vector billow = pillow+willow*(cosine(theta)*sine(theta));

JLove

### #46 2017-08-29 18:20:45

Rotation has to be applied to each component, as your first example. *But*, it's worth keeping in mind that the vector (5, 9, 0) has a direction. Think cartesian coordinates vs polar. Defining a vector as magnitude×direction is effectively using polar (r, theta), and defining a vector as x, y, and z is effectively telling the vector to point to the cartesian point (x, y, z). If your vector is (0.707, 0.707), its length is 1 and its direction is pi/4 (45dg).

So the answer is "the first one, usually".

### #47 2017-08-29 20:29:21

Um, weird error here:

#include "math.bgt"

#include "ball.bgt"

#include "clock.bgt"

ball B;

clock C(50);

in clock:

class clock

{

timer time;

...

}

in ball:

double DT = C.time.elapsed;

compiler responds:

Line: double DT = C.time.elapsed;

Error: 'time' is not a member of 'clock'

The fuck? Time is most definitely a member of clock, as seen above`.

### #48 2017-08-29 22:57:40

... Yeah, I'm not sure what that's about. Are there two clock classes, somehow? Like, in clock.bgt and ball.bgt?

I think dt should probably be 0.001×C.time.elapsed, though, or you'll probably wind up with the same online synching issue from before.

### #50 2017-08-29 23:32:11

Should I use: double DT = 0.001*C.time.elapsed, or should I use: double DT = C.delay?

By the way, I get the same error with using delay in lieu of time.elapsed:

Line: double DT = 0.001*C.delay;

Error: 'delay' is not a member of 'clock'

The clock code is as follows:

class clock

{

timer time;

uint frame = 0;

double delay = 5;

clock(double fps)

{

delay = 1000.0/fps;

time.restart();

}

void tick()

{

double elapsed=time.elapsed-delay+1;

time.restart();

time.resume();

wait((elapsed>=delay) ? 1 : delay-elapsed);

frame++;

}

bool update()

{

if (time.elapsed>=delay) {

time.restart();

time.resume();

return true;

}

return false;

}

}

Looks like both of those are members of clock. So what the hell?