I made a 3d vector class like this
struct Vector3D {
float x;
float y;
float z;
Vector3D() {
x = 0;
y = 0;
z = 0;
}
Vector3D(float x1,float y1,float z1=0) {
x = x1;
y = y1;
z = z1;
}
//member functions for operator overloading, dot product, etc.
};
But now I want to make a child class specific to Euler angles. So far I have
struct Euler3D : Vector3D {
float roll;
float pitch;
float yaw;
};
How do I make the class so that roll pitch and yaw reference the same data as x, y and z? I think it involves union or something.
I want to be able to achieve something like this:
Euler3D a = {1, 2, 3};
cout << a.x << endl; // prints 1
a.x = 1.5;
cout << a.roll << endl; //prints 1.5
Thank you
How do I make the class so that roll pitch and yaw reference the same data as x, y and z?
You cannot.
Since you want to refer to an object, you could use reference instead, but that breaks copying - you can fix copy constructor by using user defined one. Furthermore (just like your duplication) this introduces unnecessary memory overhead.
What you can do is write a function that returns reference to the member. like this:
struct Euler3D : Vector3D {
float& roll() { return x; }
But this is not ideal either because you probably need at least a second set of overloads for const, so plenty of boilerplate.
I think it involves union or something.
You can use an union to have aliased members, but then you cannot have the inheritance. This is allowed:
struct Euler3D {
union { float x, roll; };
union { float y, pitch; };
union { float z, yaw; };
};
Which you can use exactly as in your snippet.
How do I make the class so that roll pitch and yaw reference the same
data as x, y and z?
The clue is in the word "reference" - you can make the members of the derived class references to the corresponding members in the base.
EDIT: As pointed out in the comments, this will also require the class to have a copy constructor:
struct Euler3D : Vector3D {
float& roll = Vector3D::x; // You don't actually need the "Vector3D::" ...
float& pitch = Vector3D::y; // ... qualifiers here, but using them adds ...
float& yaw = Vector3D::z; // ... clarity for more complex cases.
Euler3D() { } // Should have def. ctor as we define the copy!
Euler3D(const Euler3D& rhs) : Vector3D(rhs) { }
};
Here's a short piece of code to illustrate how this could work:
int main()
{
Euler3D* e3d = new Euler3D;
e3d->roll = 1.1f;
e3d->pitch = 2.2f;
e3d->yaw = 3.3f;
Vector3D* v3d = dynamic_cast<Vector3D*>(e3d);
std::cout << v3d->x << " " << v3d->y << " " << v3d->z << std::endl;
Euler3D e3d2 = *e3d;
std::cout << e3d2.roll << " " << e3d2.pitch << " " << e3d2.yaw << std::endl; // Copied from RHS
e3d2.roll = 4.4f; e3d2.pitch = 5.5f; e3d2.yaw = 6.6f;
std::cout << e3d2.roll << " " << e3d2.pitch << " " << e3d2.yaw << std::endl; // Changed
std::cout << v3d->x << " " << v3d->y << " " << v3d->z << std::endl; // Not changed
return 0;
}
Related
I'm trying to implement a simple vector-swizzling functionality as a pet project to get into template metaprogramming. With the help of open-source mathematics library glm and some other posts on SO, I have come up with a solution which is basically working but has one error.
I have implemenented several structs which hold the data I need to represent a two dimensional eucledian vector. The struct "vec2" has a union which holds a float array with two elements (float data[2]) and two instances of struct "scalarSwizzle" which is supposed to implement the swizzling mechanic which allows me to acces the vector like so vec.data[0] or so vec.x.
Following the code I implemented so far:
#include <iostream>
template<typename T>
void print(T value)
{
std::cout << "print func: " << value << std::endl;
}
template<typename T, unsigned int I>
struct scalarSwiz
{
T value[1];
T &operator=(const T newValue)
{
value[I] = newValue;
return value[I];
}
operator T()
{
return value[I];
}
};
template<typename T>
struct vec2
{
union
{
T data[2];
scalarSwiz<T, 0> x;
scalarSwiz<T, 1> y;
};
vec2()
{
x = 0.0f;
y = 1.0f;
}
vec2(T pA, T pB)
{
x = pA;
y = pB;
}
};
int main(int argc, char *args[])
{
vec2<float> vec1{5.0f, 1.0f};
std::cout << "value vec1.data[0]: " << vec1.data[0] << std::endl;
std::cout << "value vec1.data[1]: " << vec1.data[1] << std::endl;
std::cout << "value vec1.x: " << vec1.x << std::endl;
std::cout << "value vec1.y: " << vec1.y << std::endl << std::endl;
print(vec1.data[0]);
print(vec1.data[1]);
print(vec1.x);
print(vec1.y);
std::cin.get();
}
The output is the following:
value vec1.data[0]: 5
value vec1.data[1]: 567.4
value vec1.x: 5
value vec1.y: 567.4
print func: 5
print func: 567.4
print func: 5
print func: 2.5565e-39
I expected the output to be the same for both printing the values directly in main() and via print() but vec.y is not resolved when I print it via the print() function. So I guess something is wrong with the overloaded typecast operator in "scalarSwizzle" but i have no idea what.
What I also dont understand is, why visual studio also doesn't resolve the value properly as seen on the following image:
vec1.y seem to be pointing to the same physical address then vec.x, while the direct std::cout in main() works fine.
I've been trying for a couple of days now to wrap my head around the problem, why the overloaded typecast operator doesnt work for vec.y but i just dont get it. Maybe someone here can help my with this problem.
Thank you!
First of all
template<typename T, unsigned int I>
struct scalarSwiz
{
T value[1];
T &operator=(const T newValue)
{
value[I] = newValue;
return value[I];
}
operator T()
{
return value[I];
}
};
results in undefined behavior if I != 0 (array access out of bounds) so don't expect your code to be correct or even stable.
Secondly, accessing an inactive member of a union is also undefined behavior (as per c++ standard). However, msvc, gcc and clang extend the c++ standard so that accessing inactive member behaves like we expect it to.
And finally, your scalarSwiz type can be replaced by an anonymous struct:
template<typename T>
struct vec2
{
union
{
T data[2];
struct
{
T x, y;
};
};
vec2()
{
x = 0.0f;
y = 1.0f;
}
vec2(T pA, T pB)
{
x = pA;
y = pB;
}
};
In regards to your Visual Studio debugger display: this is because of your scalarSwiz definition. You define an array of length 1 T value[1] and you put 2 scalarSwiz objects in a union. Because every member of a union share the same memory (or rather start at the same memory location), both of your value members point to the beginning of the data array. The watch window only displays the members and their values of a certain type, it has no knowledge of your quirky indexing. And because both arrays occupie the same memory, the same value is shown.
I updated my code regarding Timo's answer:
#include <iostream>
template<typename T>
void print(T value)
{
std::cout << "print func: " << value << std::endl;
}
template<typename T>
struct vec2
{
union
{
T data[2];
struct
{
T x, y;
};
};
vec2()
{
x = 0.0f;
y = 1.0f;
}
vec2(T pA, T pB)
{
x = pA;
y = pB;
}
};
int main(int argc, char *args[])
{
vec2<float> vec1{5.0f, 1.0f};
std::cout << "value vec1.data[0]: " << vec1.data[0] << std::endl;
std::cout << "value vec1.data[1]: " << vec1.data[1] << std::endl;
std::cout << "value vec1.x: " << vec1.x << std::endl;
std::cout << "value vec1.y: " << vec1.y << std::endl << std::endl;
print(vec1.data[0]);
print(vec1.data[1]);
print(vec1.x);
print(vec1.y);
std::cin.get();
}
I'm trying to find a way to get an iterator to work on a list of custom objects and a list of objects derived from that custom object. My, perhaps misguided, goal is to allow me to leave the "production" code and objects intact yet accessible from the "experimental/extended" things that I'm trying out.
Here's a pretty minimal example of what I'm trying to do.
#include <iostream>
#include <list>
using std::cout;
using std::endl;
using std::cin;
using std::list;
struct comp{
double x,y;
void print(){
cout << "x: " << x << endl;
cout << "y: " << y << endl;
}
comp(){
x = 0;
y = 0;
}
comp(double X, double Y){
x = X;
y = Y;
}
// Standard/Tested Member Functions
};
struct base{
list<comp> components;
double known, tested, variables;
void print_comps(){
for (list<comp>::iterator it = components.begin(); it != components.end(); ++it){
// Ideally, this function should work for comp1 and comp1x
// as inherited in the basex class
it->print();
}
}
// Standard/Tested Member Functions
};
struct compx : comp{
double w,z;
double some, alter, nates;
void print(){
cout << "x: " << x << endl;
cout << "y: " << y << endl;
cout << "w: " << w << endl;
cout << "z: " << z << endl;
}
compx(){
x = 0;
y = 0;
z = 0;
w = 0;
}
compx(double X, double Y, double Z, double W){
x = X;
y = Y;
z = Z;
w = W;
}
// Experimental/Un-tested Member Functions
};
struct basex : base{
list<compx> components;
double exper, imen, tal;
// void print_comps(){} // This should be inherited from base
// Experimental/Un-tested Member Functions
};
int main(){
base compilation1;
compilation1.components.push_back(comp(1,2));
compilation1.components.push_back(comp(3,4));
cout << "printing normal struct" << endl;
compilation1.print_comps();
cout << endl;
basex compilation2;
compilation2.components.push_back(compx(9, 5, 5, 6));
compilation2.components.push_back(compx(7, 2, 1, 8));
cout << "printing extended struct" << endl;
compilation2.print_comps(); // Prints nothing
cout << endl;
cout << "Printing via specific iterator" << endl;
for (list<compx>::iterator it = compilation2.components.begin(); it != compilation2.components.end(); ++it){
it->print(); // Works as expected.
}
cout << endl << endl << "Press ENTER to exit." << endl; cin.get();
return 0;
}
Ideally, I would be able to iterate over both the original class and the extended class in the same functions so I don't clutter the extended class with all the original code. This would allow me to simply move code from the extended class to the original class as those variables or functions are proven or matured.
Background:
I'm not married to lists -- any other iterable class would be fine.
I'm not a developer -- I'm a ChemE trying to make daily tasks a bit easier without breaking what I've already built.
Branches in a git repository are not a great solution because other non-developer, potentially code-challenged, folks may try to extend this. Getting them to use even one branch would be a miracle.
I'm using g++ 7.4.0 on Linux (Lubuntu) and 6.3.0 on Windows 7.
TL;DR:
Is there a way to get an iterator of list<parent_object> to also iterate over list<child_object>?
This could be solved by having base as a template http://cpp.sh/7r2x6a
template<typename T>
struct base
{
list<T> components;
double known, tested, variables;
void print_comps(){
for (auto it = components.begin(); it != components.end(); ++it){
// Ideally, this function should work for comp1 and comp1x
// as inherited in the basex class
it->print();
}
}
// Standard/Tested Member Functions
};
If you're okay with not being able to mix comp and compx objects together in the same list, then you can use a templated function to avoid duplicate code.
For example, you can do the following in your struct base:
struct base{
list<comp> components;
double known, tested, variables;
void print_comps() {print_comps_aux<comp>(components);}
protected:
template <typename CompType> void print_comps_aux(list<CompType> & compsArg)
{
for (typename list<CompType>::iterator it = compsArg.begin(); it != compsArg.end(); ++it){
it->print();
}
}
// Standard/Tested Member Functions
};
... and then in your struct basex you can just have this:
[...]
void print_comps() {print_comps_aux<compx>(components);}
I'm trying to make a fairly basic program but I'm getting some very inconsistent outputs. In particular the setter doesn't seem to be setting values, although when I mess with the argument variables in ways which shouldn't alter the output I'm sometimes getting working results.
Here is my code:
point.cpp
public:
point()
{
x = 0;
y = 0;
}
point(double x, double y)
{
x = x;
y = y;
}
void set_x(double x)
{
x = x;
}
void set_y(double y)
{
y = y;
}
double get_x() const
{
return x;
}
double get_y() const
{
return y;
}
private:
double x;
double y;
};
Main
point pointA;
double x,y;
cout << "Enter x value for point A: " << endl;
cin >> x;
pointA.set_x(x);
cout << "Enter y value for point A: " << endl;
cin >> y;
pointA.set_y(y);
point pointB(x,y);
cout << "X value for point A is: " << pointA.get_x() << endl;
cout << "Y value for point A is: " << pointA.get_y() << endl;
cout << "X value for point B is: " << pointB.get_x() << endl;
cout << "Y value for point B is: " << pointB.get_y() << endl;
Output:
X value for point A is: 10
Y value for point A is: 10
X value for point B is: 3.18463e-314
Y value for point B is: 2.12199e-314
I'm really confused about all this since essentially the same functions are working in other similarly basic programs. If anyone could point out what obvious mistake I'm making it would be greatly appreciated.
Let's examine one constructor, though the problem is the same everywhere
point(double x, double y)
{
x = x;
y = y;
}
x refers to to the parameter. So you are assigning the parameter to itself. Two and a half solutions are possible:
Use different names for the members and parameters.
Explicitly name the member with this, i.e. this->x = x;.
For the c'tor only. Use a member initializer list, point(double x, double y) : x(x), y(y) {}. Here there are special rules about what x is being referred to inside and outside the initializer. I recommend you use a member initializer list even if you adopt one of the previous solutions. It's more idiomatic C++.
The problem - as stated already by others - is that your member variable has the same name as the parameter.
Take a look at this method by itself. It is complete and does assign x to itself.
void set_x(double x)
{
x = x;
}
In your code this double x hides the external (from the functions point of view) variable x.
I would recommend to prefix you member variables with m_ or m (m for member).
This would make for unique names and help you distinguish and prevent such problems.
void set_x(double x)
{
m_x = x;
}
Now you can see that the parameter x is assigned to the member variable m_x.
Alternatively you can also refer to the member with the same name by using the this-Pointer like this:
void set_x(double x)
{
this->x = x;
}
I'm new to C++
below is the code for converting object of english distance(feet' inches") to meters and vice versa
#include <iostream>
using namespace std;
class Distance
{
private:
const float MTF;
int feet;
float inches;
public:
Distance() : feet(0), inches(0.0), MTF(3.280833F) //no argument constructor
{ }
Distance(float meters) : MTF(3.28033F)//(1-arg constructor)
{//coverting metres to distance object
float fltfeet = MTF * meters;
feet = int(fltfeet);
inches = 12*(fltfeet-feet);
}
Distance(int ft, float in) : feet(ft), inches(in), MTF(3.280833F)
{ }
void getdist()//get distance from user
{
cout << "\nEnter feet: "; cin >> feet;
cout << "Enter inches: "; cin >> inches;
}
void showdist() const // o/p the distance
{ cout << feet << "\'-" << inches << '\"'; }
operator float() const //conversion operator
{ // converts distance to meters
float fracfeet = inches/12;
fracfeet += static_cast<float>(feet);
return fracfeet/MTF;
}
};
int main()
{
float mtrs;
Distance dist1 = 2.35F; //meters to distance
cout << "\ndist1 = "; dist1.showdist();
mtrs = static_cast<float>(dist1); //casting distance to meters
cout << "\ndist1 = " << mtrs << " meters\n";
Distance dist2(5, 10.25);
mtrs = dist2; //casting dist2 to meters
cout << "\ndist2 = " << mtrs << " meters\n";
Distance dist3; //new object dist3
dist3 = mtrs; //here is the error
//not converting meters to distance object
cout<<"\ndist3 = ";dist3.showdist();
return 0;
}
but the code shows the error :
In member function 'Distance& Distance::operator=(const Distance&)':
error: non-static const member 'const float Distance::MTF', can't use default assignment operator
should'nt it be converting mtrs to object dist3 ?
why error occurs?
You error is actually with the line
dist3 = mtrs;
not
Distance dist3;
The reason for this is Distance has a const member variable. Since it is const it cannot be assigned to which cause the default copy assignment and move assignment operators to be deleted.
You are going to have to rethink your design if you want to allow assignment of your objects or write your own custom assignment functions.
You have to override assignment operator. And the code should be as shown below
#include <iostream>
using namespace std;
class Distance
{
private:
const float MTF;
int feet;
float inches;
public:
Distance() : feet(0), inches(0.0), MTF(3.280833F)
{ }
Distance(float meters) : MTF(3.28033F)
{
float fltfeet = MTF * meters;
feet = int(fltfeet);
inches = 12*(fltfeet-feet);
}
Distance(int ft, float in) : feet(ft), inches(in), MTF(3.280833F)
{ }
void getdist()
{
cout << "\nEnter feet: "; cin >> feet;
cout << "Enter inches: "; cin >> inches;
}
void showdist() const
{ cout << feet << "\'-" << inches << '\"'; }
operator float() const
{
float fracfeet = inches/12;
fracfeet += static_cast<float>(feet);
return fracfeet/MTF;
}
Distance& operator=(const Distance & otherD)
{
feet = otherD.feet;
inches = otherD.inches;
return *this;
}
};
int main()
{
float mtrs;
Distance dist1 = 2.35F;
cout << "\ndist1 = "; dist1.showdist();
mtrs = static_cast<float>(dist1);
cout << "\ndist1 = " << mtrs << " meters\n";
Distance dist2(5, 10.25);
mtrs = dist2;
cout << "\ndist2 = " << mtrs << " meters\n";
Distance dist3; //here is the error
dist3 = (Distance)mtrs ;
//cout<<"\ndist3 = ";dist3.showdist();
return 0;
}
Like another user said, you have a "const" variable, so you have to override assigment operator to address your requirements.
If you want to have class scope constant, you better change your class definition to:
class Distance
{
private:
static constexpr float MTF = 3.280833F;
int feet;
float inches;
public:
Distance() : feet(0), inches(0.0)
...
This will eliminate error you get and will work as you intended. Plus you do not have to define that constant value multiple times as you have in your code.
Note: if you cannot use C++11 you can make MTF global constant (better in unnamed namespace inside cpp file) or just static member. Either way it will eliminate the error and you will need to define it only once, which is less error prone.
I gather that the error comes at the line
dist3 = mtrs;
The problem here is that Distance does not have an assignment operator that takes an argument of type float, so the compiler tries to create a temporary object of type Distance and construct it with the argument mtrs; that's okay, but the next step is to assign that temporary value to dist3, and the compiler is complaining that it can't assign the value of MTF in the temporary object to the value of MTF in dist3 because MTF is const.
Because of that const, objects of type Distance cannot be assigned. So, for example, dist3 = dist2 would also fail. That's probably not what you intended, and you can fix this by adding an assignment operator that simply ignores the value of MTF.
The error occurs, because you could not declare const inside a class. You should define the const variable outside the class. You should replace const float MTF with float MTF here.
As stated in other answers, the issue is that you have declared the MTF variable as const. There are ways around this though. You've set the variable to be const because it's a constant and shouldnt change. Instead, add a dedicated Distance& operator=(float feet) Method in which you actually set the feet and inches variable when passed in a float value:
class Distance
{
private:
/* ... */
public:
/* ... */
Distance& operator=(float feet)
{
// Set the feet and inches here from
// the passed feet variable
return *this;
}
};
That should solve the problem of assigning the variable from a float.
This I feel is a rather complicated problem, I hope I can fit it in to small enough of a space to make it understandable. I'm presently writing code to
simulate Ideal gas particles inside a box. I'm calculating if two particles will collide having calculated the time taken for them to reach their closest point. (using an example where they have head on collision).
In this section of code I need to find if they will collide at all for two particles, before then calculating at what time and how they collide etc.
Thus for my two paricles:
Main.cpp
Vector vp1(0,0,0);
Vector vv1(1,0,0);
Vector vp2(12,0,0);
Vector vv2(-1,0,0);
Particle Particle1(1, vp1, vv1);
Particle Particle2(1, vp2, vv2);
Particle1.timeToCollision(Particle2);
Within my program I define a particle to be:
Header File
class Particle {
private:
Vector p; //position
Vector v; //velocity
double radius; //radius
public:
Particle();
Particle(double r, const Vector Vecp, const Vector Vecv);
void setPosition(Vector);
void setVelocity(Vector);
Vector getPosition() const;
Vector getVelocity() const;
double getRadius() const;
void move(double t);
double timeToCollision(const Particle particle);
void collideParticles(Particle);
~Particle();
};
Vector is another class that in short gives x, y, z values. It also contains multiple functions for manipulating these.
And the part that I need help with, within the .cpp (Ignore the cout start and letters etc, they are simple checks where my code exits for tests.)
Given the equations:
I have already written code to do the dot product and modulus for me and:
where
s is distance travelled in time tac.
double Particle::timeToCollision(const Particle particle){
Vector r2 = particle.getPosition();
Vector r1 = p;
Vector v2 = particle.getVelocity();
Vector v1 = v;
Vector r0 = r2 - r1;
Vector v = v2 - v1;
double modv;
double tca;
double result = 0;
double bsqr;
modv = getVelocity().modulus();
cout << "start" << endl;
if(modv < 0.0000001){
cout << "a" << endl;
result = FLT_MAX;
}else{
cout << "b" << endl;
tca = ((--r0).dot(v)) / v.modulusSqr();
// -- is an overridden operator that gives the negation ( eg (2, 3, 4) to (-2, -3, -4) )
if (tca < 0) {
cout << "c" << endl;
result = FLT_MAX;
}else{
cout << "d" << endl;
Vector s(v.GetX(), v.GetY(), v.GetZ());
s.Scale(tca);
cout << getVelocity().GetX() << endl;
cout << getVelocity().GetY() << endl;
cout << getVelocity().GetZ() << endl;
double radsqr = radius * radius;
double bx = (r0.GetX() * r0.GetX() - (((r0).dot(v)) *((r0).dot(v)) / v.modulusSqr()));
double by = (r0.GetY() * r0.GetY() - (((r0).dot(v)) *((r0).dot(v)) / v.modulusSqr()));
double bz=(r0.GetZ() * r0.GetZ() - (((r0).dot(v)) * ((r0).dot(v)) / v.modulusSqr()));
if (bsqr < 4 * radsqr) {
cout << "e" << endl;
result = FLT_MAX;
} else {
}
cout << "tca: " << tca << endl;
}
}
cout << "fin" << endl;
return result;
}
I have equations for calculating several aspects, tca refers to Time of closest approach.
As written in the code I need to check if b > 4 r^2, I Have made some attempts and written the X, Y and Z components of b out. But I'm getting rubbish answers.
I just need help to establish if I've already made mistakes or the sort of direction I should be heading.
All my code prior to this works as expected and I've written multiple tests for each to check.
Please inform me in a comment for any information you feel I've left out etc.
Any help greatly appreciated.
You had several mistakes in your code. You never set result to a value different from 0 or FLT_MAX. You also never calculate bsqr. And I guess the collision happens if bsqr < 4r^2 and not the other way round. (well i do not understand why 4r^2 instead of r^2 but okay). Since you hide your vector implementation I used a common vector library. I also recommend to not use handcrafted stuff anyway. Take a look into armadillo or Eigen.
Here you go with a try in Eigen.
#include <iostream>
#include <limits>
#include <type_traits>
#include "Eigen/Dense"
struct Particle {
double radius;
Eigen::Vector3d p;
Eigen::Vector3d v;
};
template <class FloatingPoint>
std::enable_if_t<std::is_floating_point<FloatingPoint>::value, bool>
almost_equal(FloatingPoint x, FloatingPoint y, unsigned ulp=1)
{
FloatingPoint max = std::max(std::abs(x), std::abs(y));
return std::abs(x-y) <= std::numeric_limits<FloatingPoint>::epsilon()*max*ulp;
}
double timeToCollision(const Particle& left, const Particle& right){
Eigen::Vector3d r0 = right.p - left.p;
Eigen::Vector3d v = right.v - left.v;
double result = std::numeric_limits<double>::infinity();
double vv = v.dot(v);
if (!almost_equal(vv, 0.)) {
double tca = (-r0).dot(v) / vv;
if (tca >= 0) {
Eigen::Vector3d s = tca*v;
double bb = r0.dot(r0) - s.dot(s);
double radius = std::max(left.radius, right.radius);
if (bb < 4*radius*radius)
result = tca;
}
}
return result;
}
int main()
{
Eigen::Vector3d vp1 {0,0,0};
Eigen::Vector3d vv1 {1,0,0};
Eigen::Vector3d vp2 {12,0,0};
Eigen::Vector3d vv2 {-1,0,0};
Particle p1 {1, vp1, vv1};
Particle p2 {1, vp2, vv2};
std::cout << timeToCollision(p1, p2) << '\n';
}
My apologies for a very poorly worded question that was to long and bulky to make much sense of. Luckily I have found my own answer to be much easier then initially anticipated.
double Particle::timeToCollision(const Particle particle){
Vector r2=particle.getPosition();
Vector r1=p;
Vector v2=particle.getVelocity();
Vector v1=v;
Vector r0=r2-r1;
Vector v=v2-v1;
double modv;
double tca = ((--r0).dot(v)) / v.modulusSqr();
double bsqr;
double result=0;
double rColTestx=r0.GetX()+v.GetX()*tca;
double rColTesty=r0.GetY()+v.GetY()*tca;
double rColTestz=r0.GetZ()+v.GetZ()*tca;
Vector rtColTest(rColTestx, rColTesty, rColTestz);
modv=getVelocity().modulus();
cout << "start " << endl;
if(modv<0.0000001){
cout << "a" << endl;
result=FLT_MAX;
}else{
cout << "b" << endl;
if (tca < 0) {
cout << "c" << endl;
result=FLT_MAX;
}else{
cout << "d" << endl;
Vector s(v.GetX(), v.GetY(), v.GetZ());
s.Scale(tca);
cout << getVelocity().GetX() << endl;
cout << getVelocity().GetY() << endl;
cout << getVelocity().GetZ() << endl;
double radsqr= radius*radius;
bsqr=rtColTest.modulusSqr();
if (bsqr < 4*radsqr) {
cout << "e" << endl;
cout << "collision occurs" << endl;
result = FLT_MAX;
} else {
cout << "collision does not occurs" << endl;
}
}
}
cout << "fin" << endl;
return result;
}
Sorry its a large section of code. Also FLT_MAX is from the cfloat lib. I didn't stat this in my question. I found this to work for several examples I calculated on paper to check.
To be Clear, the return resultand result=0 were arbitrary. I later edit to return time but for this part didn't need or want that.