I'm Confused about a topic regarding operator overloading. See the following code:
#include <iostream>;
class Vectors {
public:
int x, y;
Vectors() {};
Vectors(int a,int b) {
x = a, y = b;
}
Vectors operator+(Vectors aso) {
Vectors brandNew;
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
brandNew.x = brandNew.x + aso.x;
brandNew.y = brandNew.y + aso.y;
return (brandNew);
};
};
int main() {
Vectors v1(2,3);
Vectors v2(4,5);
Vectors v3;
v3 = v1 + v2;
std::cout << "Vector V3 X : " << v3.x << std::endl;
std::cout << "VECTOR V3 Y : " << v3.y << std::endl;
}
When I print aso.x, it y gives me 4 and 5. What I want to do is add both v1 and v2; meaning the x of v1 and v2, and the y of v1 and v2. Then, pass it into a Vectors object and return that object.
How do I accomplish that, given what I have above?
You probably meant
Vectors operator+(const Vectors& aso) {
Vectors brandNew;
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
brandNew.x = x + aso.x;
brandNew.y = y + aso.y;
return (brandNew);
};
or
Vectors operator+(const Vectors& aso) {
Vectors brandNew(x + aso.x, y + aso.y);
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
return (brandNew);
};
As from your comment
But about if there were three.
Chain the operators like
int main() {
Vectors v1(2,3);
Vectors v2(4,5);
Vectors v3(7,11);
Vectors v4;
v4 = v1 + v2 + v3;
std::cout << "Vector V4 X : " << v4.x << std::endl;
std::cout << "Vector V4 X : " << v4.y << std::endl;
}
See Live Demo
You can also use external operator+ :
class Vectors {
public:
int x, y;
Vectors() {};
Vectors(int a,int b) {
x = a, y = b;
}
friend Vectors operator+(const Vectors& v1, const Vectors& v2);
};
Vectors operator+(const Vectors& v1, const Vectors& v2) {
Vectors brandNew;
brandNew.x = v1.x + v2.x;
brandNew.y = v1.y + v2.y;
return (brandNew);
};
int main() {
Vectors v1(2,3);
Vectors v2(4,5);
Vectors v3;
v3 = v1 + v2;
std::cout << "Vector V3 X : " << v3.x << std::endl;
std::cout << "VECTOR V3 Y : " << v3.y << std::endl;
}
You haven't initialized the x and y members of brandNew. You'll get random results.
Vectors operator+(Vectors aso) {
Vectors brandNew;
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
brandNew.x = x + aso.x;
brandNew.y = y + aso.y;
return (brandNew);
};
Your code creates the new Vectors object brandNew and then adds the values of it which are initialised to 0 to the values inside the Vectors object you passed in instead of the values in the current object. Which is why when you add v1 tov2 the result has the same values as those inside v2.
Replace
brandNew.x = brandNew.x + aso.x;
brandNew.y = brandNew.y + aso.y;
with
brandNew.x = x + aso.x;
brandNew.y = y + aso.y;
The correct definition of +operator is the following:
Vectors &operator+(const Vectors& aso)
{
std::cout << "ASO X " << aso.x << std::endl;
std::cout << "ASO Y " << aso.y << std::endl;
x = x + aso.x;
y = y + aso.y;
return (*this);
}
above code does not need temporary variable and also does not do unnecessary copy of parameters as is passed by reference.
Related
If I have a vector like this:
struct vector3D {
float x;
float y;
float z;
};
vector3D aVector = { 3.4, 4.4, 9.3 }; // my vector
How can I cout the aVector to the console?
you can overload the insertion operator << to use for your objects:
struct vector3D {
float x;
float y;
float z;
friend ostream& operator<<(ostream& out, vector3D rhs){
out << "( " << rhs.x << ", " << rhs.y << ", " << rhs.z << " )" << endl;
return out;
}
};
now you can use cout to print your object values:
int main(){
vector3D v = {10, 20, 30};
cout << v << endl;
}
Given two intersecting line segments(AB and CD) in R2 find the translation with the smallest magnitude to apply to CD so that it is no longer intersecting AB.
What I've tried. I calculate the distance from each point on each line to the opposite line. Then I pick the smallest of the 4 values and apply that to the perpendicular of the line. However, the translation I calculate is often in the wrong direction. How do I fix this?
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iterator>
class Vector2
{
public:
double x;
double y;
Vector2() : x(x), y(y) {}
Vector2(double x, double y) : x(x), y(y) {}
Vector2 operator*(double val) { return Vector2(x*val, y*val);}
Vector2 operator/(double val) { return Vector2(x/val, y/val);}
Vector2 operator+(Vector2 &v) { return Vector2(x+v.x, y+v.y);}
Vector2 operator-(Vector2 &v) { return Vector2(x-v.x, y-v.y);}
Vector2 Perpendicular() { return Vector2(y, -x); }
double Dot( Vector2 &v) {return (x * v.x) + (y * v.y); }
double Magnitude() { return std::sqrt(Dot(*this)); }
Vector2 Normal() { return *this / Magnitude(); }
double GetDistance( Vector2 &v) { Vector2 d = *this - v; return d.Magnitude(); }
};
class Line
{
public:
Line() : a(Vector2()), b(Vector2()) {}
Line( Vector2 a, Vector2 b) : a(a), b(b) {};
double DistanceFromPoint( Vector2 &p) ;
Vector2 GetTranslation( Line &l) ;
Vector2& GetPoint(unsigned i) {if (i==0) return a; else return b;}
double GetLength() { return GetPoint(0).GetDistance(GetPoint(1)); }
Vector2 a;
Vector2 b;
};
double Line::DistanceFromPoint( Vector2 &p)
{
double l2 = GetLength() * GetLength();
Vector2 pv = p - GetPoint(0);
Vector2 wv = GetPoint(1) - GetPoint(0);
double t = std::max(0.d, std::min(1.d, pv.Dot(wv) / l2));
Vector2 projection = (wv * t) + GetPoint(0);
return p.GetDistance(projection);
}
Vector2 Line::GetTranslation( Line &l)
{
// Calculate Distances from each point to rthe opposite line
std::vector<double> dist(4);
dist[0] = DistanceFromPoint(l.GetPoint(0));
dist[1] = DistanceFromPoint(l.GetPoint(1));
dist[2] = l.DistanceFromPoint(GetPoint(0));
dist[3] = l.DistanceFromPoint(GetPoint(1));
//Get the smallest distance
auto it = std::min_element(std::begin(dist), std::end(dist));
double min = *it;
unsigned pos = std::distance(std::begin(dist), it);
// Get the normalized perpendicular of line
Vector2 axis;
if (pos == 2 || pos == 3)
axis = (GetPoint(1) - GetPoint(0)).Perpendicular().Normal();
else
axis = (l.GetPoint(1) - l.GetPoint(0)).Perpendicular().Normal();
std::cout << "min: " << min << std::endl;
std::cout << "axis: (" << axis.x << "," << axis.y << ")" << std::endl;
//Apply that min to the perpendicular
return axis * min;
}
int main()
{
Line A;
Line B;
Vector2 t;
std::cout << "Left" << std::endl;
A = Line(Vector2(0, 4), Vector2(8, 4));
B = Line(Vector2(2, 0), Vector2(2, 6));
t = A.GetTranslation(B);
std::cout << "Expected: (-2, 0)" << std::endl;
std::cout << "Got: (" << t.x << "," << t.y << ")" << std::endl << std::endl;
std::cout << "Right" << std::endl;
B = Line(Vector2(6, 0), Vector2(6, 6));
t = A.GetTranslation(B);
std::cout << "Expected: (2, 0)" << std::endl;
std::cout << "translation: (" << t.x << "," << t.y << ")" << std::endl << std::endl;
std::cout << "Top" << std::endl;
B = Line(Vector2(4, 0), Vector2(4, 6));
t = A.GetTranslation(B);
std::cout << "Expected: (0, -2)" << std::endl;
std::cout << "translation: (" << t.x << "," << t.y << ")" << std::endl << std::endl;
std::cout << "Bottom" << std::endl;
B = Line(Vector2(4, 6), Vector2(4, 8));
t = A.GetTranslation(B);
std::cout << "Expected: (0, -2)" << std::endl;
std::cout << "translation: (" << t.x << "," << t.y << ")" << std::endl;
}
Your idea will work. You only need to have a signed distance function like #Tommy mentioned. Also, note that you will have to get the right perpendicular direction as well, depending on your sign conventions in the distance function.
Here is a demo
You've got the right approach. From reasoning about the Minkowski sum, the shortest vector of separation will be perpendicular to one of the lines and will be just long enough to push one of the endpoints to the surface of the other line.
However your DistanceFromPoint returns an unsigned distance: it's always zero or positive. You then use a single perpendicular per line to multiply that by. So you should end up going the wrong way 50% of the time because your distance has no sign.
You might prefer to rearrange, not least because it'll save some of your square roots:
get the two axes;
for each line, project the vector from any point on the line to each endpoint of the other line onto that line's axis. This produces a signed result;
pick the shortest of those results by magnitude;
calculate the separation axis as the negative of the shortest number times the axis it was calculated on.
... because if you're embedded by n units along axis q then the way to resolve that is to move -n units along q; so pick the least n.
I am having issues displaying coordinates that are read into a class. This is my first time using classes so please be understanding!
Here is what I have so far:
#include <iostream>
using namespace std;
class Vector{
private:
float x;
float y;
public:
Vector(float f1, float f2)
{
x=f1;
y=f2;
}
Vector(){}
float display()
{
Vector v;
cout << "(" << v.x << "," << v.y << ")" << endl;
return 0;
}
};
int main()
{
Vector v1(0.5, 0.5);
cout << "v1 ";
v1.display();
system("pause");
return 0;
}
It prints
v1 (-1.07374e+008,-1.07374e+008)
Your problem is that you are not printing out the coordinates of the Vector you created in main() but a default created one in your function. Instead of
float display()
{
Vector v;
cout << "(" << v.x << "," << v.y << ")" << endl;
return 0;
}
You need
float display()
{
//Vector v; remove this
cout << "(" << x << "," << y << ")" << endl;
// no v.x no v.y
return 0;
}
I suggest you change the default constructor to
Vector() : x(0), y(0) {}
So it would have printed
v1 (0,0)
You should also change
Vector(float f1, float f2)
{
x=f1;
y=f2;
}
To
Vector(float f1, float f2) : x(f1), y(f2) {}
As it is a good habit to get into. This can save resources and CPU cycles when dealing with non POD types. For more information see Why should I prefer to use member initialization list?
the Vector v; line is a mistake. You are basically creating a new uninitialized vector instead of crating your own instance.
one correction would be:
int display()
{
cout << "(" << x << "," << y << ")" << endl;
return 0;
}
since x and y are member of this class
I am trying, just for learning, to make a Vector class with a derived Vector3 class. The first Vector class, has a double* v; pointer for the array and some [] operators for easier data access, and Vector3 also has x, y, z pointers.
The important parts of the classes are like:
class Vector{
protected:
double* v;
int size_;
public:
[ ... a lot of stuff ... ]
double & operator [](int i);
}
class Vector3 : public Vector{
public:
double* x; //Access to v[0]
double* y; //Access to v[1]
double* z; //Access to v[2]
Vector3();
Vector3(double,double,double);
};
So my intention is to make a code like this work:
//You can create a Vector3 and access with x, y, z values:
Vector3 v3 = Vector3(10,9,8);
cout << "Testing v3.x -- v3.y -- v3.z" << endl;
cout << v3.x << " -- " << v3.y << " -- " << v3.z << endl;
//And also change its values
v3.x = 5;
v3.y = 1;
v3.z = 6;
//Now, the two following couts should print the same:
cout << "Testing v3.x -- v3.y -- v3.z and v3[0] -- v3[1] -- v3[2]" << endl;
cout << v3.x << " -- " << v3.y << " -- " << v3.z << endl;
cout << v3[0]<< " -- " << v3[1]<< " -- " << v3[2]<< endl;
And my question is:
Is it possible to do this without modifying that last code?
I know I can easily make this work changing the v3.x for v3.x[0] or something like that but I want it to be more intuitive.
If you do not need operator= for Vector3 class, you could change pointers to references.
class Vector3 : public Vector{
public:
double& x; //Access to v[0]
double& y; //Access to v[1]
double& z; //Access to v[2]
Vector3();
Vector3(double,double,double);
};
based on the example here http://www.boost.org/doc/libs/release/libs/utility/operators.htm#example, I have implemented the following derived class of boost::numeric::ublas::vector:
namespace Chebyshev
{
template<typename T>
class function_data : public boost::numeric::ublas::vector<T>,
boost::addable<function_data<T> >,
boost::subtractable<function_data<T> >,
boost::multipliable2<function_data<T>, T>,
boost::dividable2<function_data<T>, T>
{
public:
char dataflag;
function_data() : boost::numeric::ublas::vector<T>() {dataflag=0;} ///< The default empty constructor
function_data(const boost::numeric::ublas::vector<T>& vec) : boost::numeric::ublas::vector<T>(vec) {dataflag=0;} ///< The copy constructor without a flag.
function_data(const boost::numeric::ublas::vector<T>& vec, char flag) : boost::numeric::ublas::vector<T>(vec), dataflag(flag) {} ///< The copy constructor with a flag.
~function_data() {} ///< The destructor.
function_data<T>& operator= (const boost::numeric::ublas::vector<T>& in) {boost::numeric::ublas::vector<T>::operator=(in); return *this;} ///< The assignment operator from a boost::numeric::ublas::vector<T>.
function_data<T>& operator= (const function_data<T>& in) {boost::numeric::ublas::vector<T>::operator=(in); dataflag=in.dataflag; return *this;} ///< The assignment operator.
function_data<T>& operator+= (const function_data<T>& in) {this->boost::numeric::ublas::vector<T>::operator+=(in); this->dataflag=this->dataflag; return *this;}
function_data<T>& operator-= (const function_data<T>& in) {this->boost::numeric::ublas::vector<T>::operator-=(in); this->dataflag=this->dataflag; return *this;}
function_data<T>& operator*= (T in) {this->boost::numeric::ublas::vector<T>::operator*=(in); this->dataflag=this->dataflag; return *this;}
function_data<T>& operator/= (T in) {this->boost::numeric::ublas::vector<T>::operator/=(in); this->dataflag=this->dataflag; return *this;}
friend std::ostream& operator<< (std::ostream& os, const function_data<T>& fd) {os << "[type " << fd.dataflag << "] " << static_cast<boost::numeric::ublas::vector<T> >(fd); return os;} ///< The << operator.
};
}
However, compiling the following snippet of code
int main( int argc, char ** argv)
{
Chebyshev::function_data<std::complex<double> > u;
/* some stuff putting values in u */
std::cout << u*2 << std::endl;
return 0;
}
gives a "ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second" warning and proceeds to give the ublas vector_expression version (with u cast as some kind of vector_expression) and my version (with 2 cast as a const std::complex<double>&).
I would like to be able to use mixed arithmetic in my class as in the above snippet of code, but the explanation on the boost::operators website isn't clear to me. What do I have to add or change in my class to allow this?
Also, in the example, the inheritance list has each class inside the last > of the previous class. I don't see any difference in the output of the compiler whether I write it that way or the way I have above. Which is the proper way to write it?
Best regards, Brett.
Boost uBLAS has all the operators that you need to vector arithmetic. Here is a sample program to highlight it:
#include <iostream>
#include "boost/numeric/ublas/vector.hpp"
#include "boost/numeric/ublas/io.hpp"
using namespace boost::numeric::ublas;
int main()
{
vector<int> v1(4);
vector<int> v2(4);
vector<int> v3(4);
vector< std::complex<double> > v4(4);
for (size_t i = 0; i < v1.size(); i++)
v1(i) = (i + 1) * 3;
for (size_t i = 0; i < v1.size(); i++)
v2(i) = (i + 1) * 10;
for (size_t i = 0; i < v4.size(); i++)
v4(i) = std::complex<double>(v1(i), v2(i));
std::cout << "v1: " << v1 << std::endl;
std::cout << "v2: " << v2 << std::endl;
std::cout << "v3 = v2 * 3: " << (v3 = v2 * 3) << std::endl;
std::cout << "v4: " << v4 << std::endl;
std::cout << "v1 + v2: " << v1 + v2 << std::endl;
std::cout << "v1 - v2: " << v1 - v2 << std::endl;
std::cout << "v1 * 3: " << v1 * 3 << std::endl;
std::cout << "(v2 * 2) / 3: " << (v2 * 2) / 3 << std::endl;
std::cout << "v4 * 3: " << v4 * 3 << std::endl;
std::cout << "v4 + v4" << v4 + v4 << std::endl;
std::cout << "element_prod(v1, v2)" << element_prod(v1, v2) << std::endl;
std::cout << "element_div(v2, v1)" << element_div(v2, v1) << std::endl;
return 0;
}
Here is the output I got when I compiled and ran using g++ v4.1.2:
[ublas]$ g++ -o vector vector.cpp
[ublas]$ ./vector
v1: [4](3,6,9,12)
v2: [4](10,20,30,40)
v3 = v2 * 3: [4](30,60,90,120)
v4: [4]((3,10),(6,20),(9,30),(12,40))
v1 + v2: [4](13,26,39,52)
v1 - v2: [4](-7,-14,-21,-28)
v1 * 3: [4](9,18,27,36)
(v2 * 2) / 3: [4](6,13,20,26)
v4 * 3: [4]((9,30),(18,60),(27,90),(36,120))
v4 + v4[4]((6,20),(12,40),(18,60),(24,80))
element_prod(v1, v2)[4](30,120,270,480)
element_div(v2, v1)[4](3,3,3,3)