I'm writing a program, where you input triangle point coordinates, the program checks if the triangle exists and outputs the area of the triangle. I have to use pointers in the program.
class Vertex
{
private:
int x, y;
public:
Vertex(int x, int y) : x(x), y(y) {}
int getX() {
return x;
}
int getY() {
return y;
}
float getDistance(Vertex *anotherVertex)
{
float dist;
int tempx = 0, tempy = 0;
tempx = anotherVertex->getX();
tempy = anotherVertex->getY();
dist = ((tempx - x) * (tempx - x) + (tempy - y) * (tempy - y));
return dist;
}
void setCoord(int x, int y)
{
this->x = x;
this->y = y;
}
};
class Triangle
{
private:
Vertex *a, *b, *c;
public:
Triangle()
{
a = new Vertex(0, 0);
b = new Vertex(0, 0);
c = new Vertex(0, 0);
}
void Set_coord()
{
int x1, y1, x2, y2, x3, y3;
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
a->setCoord(x1, y1);
b->setCoord(x2, y2);
c->setCoord(x3, y3);
}
bool existTriangle() {
float ab = a->getDistance(b);
float bc = b->getDistance(c);
float ca = c->getDistance(a);
if (ab + bc > ca && ab + ca > bc && bc + ca > ab) {
return true;
}
else {
return false;
}
}
float getArea() {
float p;
float ab = a->getDistance(b);
float bc = b->getDistance(c);
float ca = c->getDistance(a);
p = (ab + bc + ca) / 2;
return sqrt(p * ((p - ab)*(p - bc)*(p - ca)));
}
};
I'm struggling to make the getDistance function working as I'm inexperienced with using pointers, when debugging i'm getting this error in the getX() function.
Exception thrown: read access violation.
this was 0xDDDDDDDD.
EDIT:
here is my main()
int main() {
int n = 0;
cin >> n;
vector<Triangle*> vertices;
for (int i = 0; i < n; i++) {
Triangle* newVertices = new Triangle();
newVertices->Set_coord();
vertices.push_back(newVertices);
delete newVertices;
}
for (int i = 0; i < n; i++)
{
if (vertices[i]->existTriangle())
{
cout << vertices[i]->getArea();
}
}
}
The problem is in your main function ( that's why I asked you to post it:) ):
Triangle* newVertices = new Triangle();
vertices.push_back(newVertices);
delete newVertices;
You dynamically allocate memory, that is pointed to by newVertices.
You store the pointer into the vector.
You delete the memory pointed by newVertices.
As a result, now that pointer is a dangling pointer.
So, you must not delete newVertices into the loop.
Do your thing (computer areas, check it a triangle exists, etc.), and then, when you are done, start deleting your dynamically allocating memory...
Related
I have a C# project which uses C++ classes from a library. C# classes are actually wrappers for C++ classes, they expose C++ functionality to C# client code.
In many places C++ value classes are converted to C# wrappers and backwards.
During code review I've found two ways how the classes are converted: via reinterpret_cast ( see operator * ) and via pin_ptr ( see MultiplyBy );
As you can see, both native and managed class has three 'double' fields, this is why someone was using reinterpret_cast;
In many places classes are copied from C# to C++ using memcpy:
memcpy(&NativePointInstance, &ManagedPointIntance, sizeof(double)*3);
I've heard from one developer that reinterpret_cast can be safe in some cases, when we work with C# value classes.
The question is:
When it is safe to use reinterpret_cast on C# value classes and when it is not?
What is the most correct way of converting the pointers in this case - like in operator * or like in MultiplyBy, or another alternative?
Can someone explain in details what is happening in MultiplyBy(), how these trick work?
As far as I understood, the issue may be caused by that optimizer may change fields order, GC may reorganize heap, and alignment of fields may be different between managed and native code.
// this is C++ native class
class NativePoint
{
public:
double x;
double y;
double z;
NativePoint(double x, double y, double z)
{
this->x = x;
this->y = y;
this->z = z;
}
NativePoint operator * (int value)
{
return NativePoint(x * value, y * value, z * value);
}
};
// this class managed C++ class
[StructLayout(LayoutKind::Sequential)]
public value class ManagedPoint
{
internal:
double x;
double y;
double z;
ManagedPoint(const NativePoint& p)
{
x = p.x;
y = p.y;
z = p.z;
}
public:
static ManagedPoint operator * (ManagedPoint a, double value)
{
return ManagedPoint((*reinterpret_cast<NativePoint*>(&(a))) * value);
}
ManagedPoint MultiplyBy(double value)
{
pin_ptr<ManagedPoint> pThisTmp = &*this;
NativePoint* pThis = reinterpret_cast<NativePoint*>(&*pThisTmp);
return ManagedPoint(*pThis * value);
}
};
// this should be called from C# code, or another .NET app
int main(array<System::String ^> ^args)
{
NativePoint p_native = NativePoint(1, 1, 1);
ManagedPoint p = ManagedPoint(p_native);
Console::WriteLine("p is {" + p.x + ", " + p.y + ", " + p.z + "}");
ManagedPoint p1 = p * 5;
Console::WriteLine("p1 is {" + p1.x + ", " + p1.y + ", " + p1.z + "}");
ManagedPoint p2 = p.MultiplyBy(5);
Console::WriteLine("p2 is {" + p2.x + ", " + p2.y + ", " + p2.z + "}");
Console::ReadLine();
return 0;
}
Well, I have ended up using usual constructors of native classes. It looks for me absolutely safe, and fastest from remaining variants. The idea from comments with Marshal::PtrToStructure() was good, but for my test example gave slower execution, than the same with using constructors. Pointer casts are the fastest solution, but after very scary example from comments, I will not risk to use it anymore (except if we really need to optimize it, then LayoutKind::Explicit should do the thing).
Here is code i used for testing:
// this is C++ native class
class NativePoint
{
public:
double x;
double y;
double z;
NativePoint()
{
}
NativePoint(double x, double y, double z)
{
this->x = x;
this->y = y;
this->z = z;
}
NativePoint operator * (int value)
{
return NativePoint(x * value, y * value, z * value);
}
};
// this class managed C++ class
[StructLayout(LayoutKind::Sequential)]
public value class ManagedPoint
{
internal:
double x;
double y;
double z;
ManagedPoint(const NativePoint& p)
{
x = p.x;
y = p.y;
z = p.z;
}
ManagedPoint(double x, double y, double z)
{
this->x = x;
this->y = y;
this->z = z;
}
public:
static ManagedPoint operator * (ManagedPoint a, double value)
{
return ManagedPoint((*reinterpret_cast<NativePoint*>(&(a))) * value);
}
ManagedPoint MultiplyBy(double value)
{
pin_ptr<ManagedPoint> pThisTmp = &*this;
NativePoint* pThis = reinterpret_cast<NativePoint*>(&*pThisTmp);
return ManagedPoint(*pThis * value);
}
};
// this class managed C++ class
[StructLayout(LayoutKind::Sequential)]
public value class ManagedPoint2
{
internal:
double x;
double y;
double z;
ManagedPoint2(const NativePoint& p)
{
x = p.x;
y = p.y;
z = p.z;
}
ManagedPoint2(double x, double y, double z)
{
this->x = x;
this->y = y;
this->z = z;
}
public:
static ManagedPoint2 operator * (ManagedPoint2 a, double value)
{
return ManagedPoint2((NativePoint(a.x, a.y, a.z)) * value);
}
ManagedPoint2 MultiplyBy(double value)
{
return ManagedPoint2((NativePoint(this->x, this->y, this->z)) * value);
}
};
// this class managed C++ class
[StructLayout(LayoutKind::Sequential)]
public value class ManagedPoint3
{
internal:
double x;
double y;
double z;
ManagedPoint3(const NativePoint& p)
{
x = p.x;
y = p.y;
z = p.z;
}
ManagedPoint3(double x, double y, double z)
{
this->x = x;
this->y = y;
this->z = z;
}
public:
static ManagedPoint3 operator * (ManagedPoint3 a, double value)
{
NativePoint p;
Marshal::StructureToPtr(a, IntPtr(&p), false);
return ManagedPoint3(p * value);
}
ManagedPoint3 MultiplyBy(double value)
{
NativePoint p;
Marshal::StructureToPtr(*this, IntPtr(&p), false);
return ManagedPoint3(p * value);
}
};
// this class managed C++ class
[StructLayout(LayoutKind::Sequential)]
public value class ManagedPoint4
{
internal:
double x;
double y;
double z;
ManagedPoint4(const NativePoint& p)
{
x = p.x;
y = p.y;
z = p.z;
}
ManagedPoint4(double x, double y, double z)
{
this->x = x;
this->y = y;
this->z = z;
}
public:
static ManagedPoint4 operator * (ManagedPoint4 a, double value)
{
return ManagedPoint4(ManagedPoint4::ToNative(a) * value);
}
ManagedPoint4 MultiplyBy(double value)
{
return ManagedPoint4(ManagedPoint4::ToNative(*this) * value);
}
static NativePoint ToNative(const ManagedPoint4& pp)
{
NativePoint p;
Marshal::StructureToPtr(pp, IntPtr(&p), false);
return p;
}
};
// this should be called from C# code, or another .NET app
int main(array<System::String ^> ^args)
{
Stopwatch time;
time.Start();
for (int i = 0; i < 10000000; i++)
{
ManagedPoint a = ManagedPoint(1, 2, 3) * 4;
}
time.Stop();
Console::WriteLine("time: " + time.ElapsedMilliseconds);
Stopwatch time2;
time2.Start();
for (int i = 0; i < 10000000; i++)
{
ManagedPoint2 a2 = ManagedPoint2(1, 2, 3) * 4;
}
time2.Stop();
Console::WriteLine("time2: " + time2.ElapsedMilliseconds);
Stopwatch time3;
time3.Start();
for (int i = 0; i < 10000000; i++)
{
ManagedPoint3 a3 = ManagedPoint3(1, 2, 3) * 4;
}
time3.Stop();
Console::WriteLine("time3: " + time3.ElapsedMilliseconds);
Stopwatch time4;
time4.Start();
for (int i = 0; i < 10000000; i++)
{
ManagedPoint4 a3 = ManagedPoint4(1, 2, 3) * 4;
}
time4.Stop();
Console::WriteLine("time4: " + time4.ElapsedMilliseconds);
Console::ReadLine();
Console::WriteLine("======================================================");
Console::WriteLine();
return 0;
}
And this is output:
time: 374
time2: 382
time3: 857
time4: 961
time: 395
time2: 413
time3: 900
time4: 968
time: 376
time2: 378
time3: 840
time4: 909
I don't know why but my program triggers a breakpoint on a line on the first iterations of 2 embedded loops here is the line:
pointerHolder->linkedVertices.push_back(&sphereApproximation.vertices.back());
Here is the section within which this resides (the line is near the bottom):
static const vertice holder[6] = { vertice(0,r,0,0), vertice(r,0,0,0), vertice(0,0,r,0), vertice(0,-r,0,0), vertice(-r,0,0,0), vertice(0,0,-r,0) };
std::vector<vertice> vertices (holder, holder + (sizeof(holder) / sizeof(vertice)));
shape sphereApproximation = shape(0, vertices);
int count;
for (int i = 0; i < 6; i++) {
count = i;
for (int t = 0; t < 5; t++) {
if (count == 5) {
count = 0;
}
else {
count++;
}
if (t != 2) {
sphereApproximation.vertices[i].linkedVertices.push_back(&sphereApproximation.vertices[count]);
}
}
}
bool * newConnection = new bool[pow(sphereApproximation.vertices.size(), 2) - sphereApproximation.vertices.size()]();
vertice * pointerHolder;
for (int i = 0; i < sphereApproximation.vertices.size(); i++) {
for (int t = 0; t < sphereApproximation.vertices[i].linkedVertices.size(); t++) {
if (!newConnection[(i * (sphereApproximation.vertices.size() - 1)) + t]) {
pointerHolder = sphereApproximation.vertices[i].linkedVertices[t];
sphereApproximation.vertices.push_back(newVertice(&sphereApproximation.vertices[i], pointerHolder, accuracyIterator + 1));
for (int q = 0; q < pointerHolder->linkedVertices.size(); q++) {
if (pointerHolder->linkedVertices[q] == &sphereApproximation.vertices[i]) {
pointerHolder->linkedVertices.erase(pointerHolder->linkedVertices.begin() + q);
break;
}
}
sphereApproximation.vertices[i].linkedVertices.erase(sphereApproximation.vertices[i].linkedVertices.begin() + t);
sphereApproximation.vertices[i].linkedVertices.push_back(&sphereApproximation.vertices.back());
std::cout << "gets here" << std::endl;
pointerHolder->linkedVertices.push_back(&sphereApproximation.vertices.back());
std::cout << "does not get here" << std::endl;
sphereApproximation.vertices.back().linkedVertices.push_back(&sphereApproximation.vertices[i]);
sphereApproximation.vertices.back().linkedVertices.push_back(pointerHolder);
}
}
}
I know the declaration for the newVertice(...) subroutine is missing, but I thought it was rather unnecessary, all that needs to be known is that its return type is vertice and it does return a vertice as I have tested. Here are the declerations of the structs I'm using:
struct vertice {
int accuracy;
double x, y, z;
std::vector<vertice*> linkedVertices;
vertice(double x, double y, double z, std::vector<vertice*> linkedVertices) {
this->x = x;
this->y = y;
this->z = z;
this->linkedVertices = linkedVertices;
}
vertice(double x, double y, double z, int accuracy) {
this->x = x;
this->y = y;
this->z = z;
this->accuracy = accuracy;
}
};
struct shape {
double center;
std::vector<vertice> vertices;
shape(double center, std::vector<vertice> vertices) {
this->center = center;
this->vertices = vertices;
}
};
If I've failed to provide anything please drop a comment and I shall amend my question.
Is there any way I can modify the poisson-disk points generator finding here.I need to generate new poisson points using the coordinates of points in the textfile.txt to improve the distribution. below the c++ code of poisson-disk sampling in a unit square.
poissonGenerator.h:
#include <vector>
#include <random>
#include <stdint.h>
#include <time.h>
namespace PoissoGenerator
{
class DefaultPRNG
{
public:
DefaultPRNG()
: m_Gen(std::random_device()())
, m_Dis(0.0f, 1.f)
{
// prepare PRNG
m_Gen.seed(time(nullptr));
}
explicit DefaultPRNG(unsigned short seed)
: m_Gen(seed)
, m_Dis(0.0f, 1.f)
{
}
double RandomDouble()
{
return static_cast <double>(m_Dis(m_Gen));
}
int RandomInt(int Max)
{
std::uniform_int_distribution<> DisInt(0, Max);
return DisInt(m_Gen);
}
private:
std::mt19937 m_Gen;
std::uniform_real_distribution<double> m_Dis;
};
struct sPoint
{
sPoint()
: x(0)
, y(0)
, m_valid(false){}
sPoint(double X, double Y)
: x(X)
, y(Y)
, m_valid(true){}
double x;
double y;
bool m_valid;
//
bool IsInRectangle() const
{
return x >= 0 && y >= 0 && x <= 1 && y <= 1;
}
//
bool IsInCircle() const
{
double fx = x - 0.5f;
double fy = y - 0.5f;
return (fx*fx + fy*fy) <= 0.25f;
}
};
struct sGridPoint
{
sGridPoint(int X, int Y)
: x(X)
, y(Y)
{}
int x;
int y;
};
double GetDistance(const sPoint& P1, const sPoint& P2)
{
return sqrt((P1.x - P2.x)*(P1.x - P2.x) + (P1.y - P2.y)*(P1.y - P2.y));
}
sGridPoint ImageToGrid(const sPoint& P, double CellSize)
{
return sGridPoint((int)(P.x / CellSize), (int)(P.y / CellSize));
}
struct sGrid
{
sGrid(int W, int H, double CellSize)
: m_W(W)
, m_H(H)
, m_CellSize(CellSize)
{
m_Grid.resize((m_H));
for (auto i = m_Grid.begin(); i != m_Grid.end(); i++){ i->resize(m_W); }
}
void Insert(const sPoint& P)
{
sGridPoint G = ImageToGrid(P, m_CellSize);
m_Grid[G.x][G.y] = P;
}
bool IsInNeighbourhood(sPoint Point, double MinDist, double CellSize)
{
sGridPoint G = ImageToGrid(Point, CellSize);
//number of adjacent cell to look for neighbour points
const int D = 5;
// Scan the neighbourhood of the Point in the grid
for (int i = G.x - D; i < G.x + D; i++)
{
for (int j = G.y - D; j < G.y + D; j++)
{
if (i >= 0 && i < m_W && j >= 0 && j < m_H)
{
sPoint P = m_Grid[i][j];
if (P.m_valid && GetDistance(P, Point) < MinDist){ return true; }
}
}
}
return false;
}
private:
int m_H;
int m_W;
double m_CellSize;
std::vector< std::vector< sPoint> > m_Grid;
};
template <typename PRNG>
sPoint PopRandom(std::vector<sPoint>& Points, PRNG& Generator)
{
const int Idx = Generator.RandomInt(Points.size() - 1);
const sPoint P = Points[Idx];
Points.erase(Points.begin() + Idx);
return P;
}
template <typename PRNG>
sPoint GenerateRandomPointAround(const sPoint& P, double MinDist, PRNG& Generator)
{
// Start with non-uniform distribution
double R1 = Generator.RandomDouble();
double R2 = Generator.RandomDouble();
// radius should be between MinDist and 2 * MinDist
double Radius = MinDist * (R1 + 1.0f);
//random angle
double Angle = 2 * 3.141592653589f * R2;
// the new point is generated around the point (x, y)
double X = P.x + Radius * cos(Angle);
double Y = P.y + Radius * sin(Angle);
return sPoint(X, Y);
}
// Return a vector of generated points
// NewPointsCount - refer to bridson-siggraph07-poissondisk.pdf
// for details (the value 'k')
// Circle - 'true' to fill a circle, 'false' to fill a rectangle
// MinDist - minimal distance estimator, use negative value for default
template <typename PRNG = DefaultPRNG>
std::vector<sPoint> GeneratePoissonPoints(rsize_t NumPoints, PRNG& Generator, int NewPointsCount = 30,
bool Circle = true, double MinDist = -1.0f)
{
if (MinDist < 0.0f)
{
MinDist = sqrt(double(NumPoints)) / double(NumPoints);
}
std::vector <sPoint> SamplePoints;
std::vector <sPoint> ProcessList;
// create the grid
double CellSize = MinDist / sqrt(2.0f);
int GridW = (int)(ceil)(1.0f / CellSize);
int GridH = (int)(ceil)(1.0f / CellSize);
sGrid Grid(GridW, GridH, CellSize);
sPoint FirstPoint;
do
{
FirstPoint = sPoint(Generator.RandomDouble(), Generator.RandomDouble());
} while (!(Circle ? FirstPoint.IsInCircle() : FirstPoint.IsInRectangle()));
//Update containers
ProcessList.push_back(FirstPoint);
SamplePoints.push_back(FirstPoint);
Grid.Insert(FirstPoint);
// generate new points for each point in the queue
while (!ProcessList.empty() && SamplePoints.size() < NumPoints)
{
#if POISSON_PROGRESS_INDICATOR
// a progress indicator, kind of
if (SamplePoints.size() % 100 == 0) std::cout << ".";
#endif // POISSON_PROGRESS_INDICATOR
sPoint Point = PopRandom<PRNG>(ProcessList, Generator);
for (int i = 0; i < NewPointsCount; i++)
{
sPoint NewPoint = GenerateRandomPointAround(Point, MinDist, Generator);
bool Fits = Circle ? NewPoint.IsInCircle() : NewPoint.IsInRectangle();
if (Fits && !Grid.IsInNeighbourhood(NewPoint, MinDist, CellSize))
{
ProcessList.push_back(NewPoint);
SamplePoints.push_back(NewPoint);
Grid.Insert(NewPoint);
continue;
}
}
}
#if POISSON_PROGRESS_INDICATOR
std::cout << std::endl << std::endl;
#endif // POISSON_PROGRESS_INDICATOR
return SamplePoints;
}
}
and the main program is:
poisson.cpp
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <fstream>
#include <memory.h>
#define POISSON_PROGRESS_INDICATOR 1
#include "PoissonGenerator.h"
const int NumPoints = 20000; // minimal number of points to generate
int main()
{
PoissonGenerator::DefaultPRNG PRNG;
const auto Points =
PoissonGenerator::GeneratePoissonPoints(NumPoints,PRNG);
std::ofstream File("Poisson.txt", std::ios::out);
File << "NumPoints = " << Points.size() << std::endl;
for (const auto& p : Points)
{
File << " " << p.x << " " << p.y << std::endl;
}
system("PAUSE");
return 0;
}
Suppose you have a point in the space [0,1] x [0,1], in the form of a std::pair<double, double>, but desire points in the space [x,y] x [w,z].
The function object
struct ProjectTo {
double x, y, w, z;
std::pair<double, double> operator(std::pair<double, double> in)
{
return std::make_pair(in.first * (y - x) + x, in.second * (z - w) + w);
}
};
will transform such an input point into the desired output point.
Suppose further you have a std::vector<std::pair<double, double>> points, all drawn from the input distribution.
std::copy(points.begin(), points.end(), points.begin(), ProjectTo{ x, y, w, z });
Now you have a vector of points in the output space.
#include <iostream>
#include <string>
using namespace std;
struct Point {
private:
int xCord,yCord;
public:
void setX(int x);
void setY(int y);
int getX();
int getY();
int rotate(int x, int y, Point p1);
int moveHorizontally(int x, int a, int b);
int moveVertically(int y, int a, int b);
};
int main() {
Point p1;
p1.setX(1); //sets X
p1.setY(2); //sets Y
cout << p1.getX() << ", " << p1.getY() << endl; //prints current value of X & Y
p1.rotate(p1.getX(), p1.getY(), p1);
cout << p1.getX() << ", " << p1.getY() << endl;
return 0;
}
void Point::setX(int newX) {
xCord = newX;
}
void Point::setY(int newY) {
yCord = newY;
}
int Point::getY() { //This will just return the y Cord.
return yCord;
}
int Point::getX() { //This will just return the x Cord.
return xCord;
}
int Point::moveHorizontally(int x, int tempX, int tempY) {
//Move the point to the right if positive.
//Move the point to the left if negative.
int newX = tempX + (x);
return newX;
}
int Point::moveVertically(int y, int tempX, int tempY) {
//Move the point up if positive.
//Move the point down if negative.
int newY = tempY + (y);
return newY;
}
int Point::rotate(int tempX, int tempY, Point p1){
//(1,2) -->> (-2,1)
int tempX_DNC = tempX;
int tempY_DNC = tempY;
int quadrant;
if((tempX > 0) && (tempY > 0)) { //Quadrant 1: x(positive), y(positive) Then rotates to Quad 2
quadrant = 1;
tempX = -(tempY);
tempY = tempX_DNC;
} else if ((tempX < 0) && (tempY > 0)) { //Quadrant 2: x(negative), y(positive) Then rotates to Quad 3
quadrant = 2;
tempX = -(tempY_DNC);
tempY = tempX_DNC;
} else if ((tempX < 0) && (tempY < 0)) { //Quadrant 3: x(negative), y(negative) Then rotates to Quad 4
quadrant = 3;
tempX = -(tempY_DNC);
tempY = tempX_DNC;
} else if ((tempX > 0) && (tempY < 0)) { //Quadrant 4: x(positive), y(negative) Then rotates to Quad 1
quadrant = 4;
tempX = -(tempY_DNC);
tempY = tempX_DNC;
} else {
quadrant = 0;
}
//This will rotate the points 90* to the left.
//(1,2) will then become (-2,1)
//I could have if in quadrant1, all are positive, if in quadrant 2 the x would be negative and y would be positive
//If in quadrant 3 the x and y will both be negative, if in quadrant 4 the x would be positive and the y would be negative
cout << tempX << ", " << tempY << endl;
p1.setX(tempX);
p1.setY(tempY);
cout <<"x is: " <<p1.getX() <<endl;
cout <<"Y is: " <<p1.getY() <<endl;
}
Code is above.
So I am creating a class Point. Point has 2 private variables xCord, yCord. I want to call the rotate function and have that be able to modify the xCord, yCord but it does not. I am not sure why. I tried passing the Point p1 to the function and to see if that would fix the issue but it did not, I also tried without passing the Point p1 and just having Point p1 inside the function definition.
p1.setX(VARIABLE);
works when it is in main(). but not when I call p1.setX(VARIABLE) inside another member function.
You are passing a copy of p1 to the rotate function. Only this copy is modified.
You pass the point by value:
int rotate(int x, int y, Point p1);
^^--------pass-by-value
ie. the p1 inside the function is a copy of p1 in main that gets deleted once the function returns. If you want to change the point that is passed as parameter inside the function then pass it by reference:
int rotate(int x, int y, Point& p1);
^^--------pass-by-reference
PS: ... However, as rotate is a member function of Point you should probably rather rotate the instance on which you are calling it, change its signature to
int rotate(int x, int y);
and instead of changing the coordinates of some point passed as parameter do this:
this->setX(tempX); // this-> not really necessary, just added for clarity
this->setY(tempY);
Alternatively you keep it as is and pass the point that is supposed to be rotated as parameter, but then you should consider making the method static.
PPS: If you want to change it to pass-by-reference, you have to change the signature in the class declaration to:
int rotate(int x, int y, Point& p1);
and the definition you have to change to:
int Point::rotate(int tempX, int tempY, Point& p1) { /*...*/ }
void point::rotate() {
xcord = ycord;
ycord = xcord;
}
is all you need for basic rotation
I am having a problem with changing the coordinate of the point to ( 7,4) using the pointer variable. I just did x = 7 and y = 4, but I don't think that is correct. Can someone help ?
What I need to do:
in main()
instantiate a Point object and initialize at the time of definition
define a pointer that points to the object defined above
using the pointer variable to
update the coordinates of the point to (7,4)
display the distance from the origin
#include <iostream>
#include <math.h>
using namespace std;
class Point
{
private:
int x, y;
public:
Point(int x_coordinate, int y_coordinate);
int getVal();
double distance(double x2, double y2);
};
// Initialize the data members
Point::Point(int x_coordinate, int y_coordinate)
{
x = x_coordinate;
y = y_coordinate;
}
// Get the values of the data members.
int Point::getVal()
{
return x,y;
}
// Calculates and returns the point's distance from the origin.
double Point::distance(double x2, double y2)
{
double d;
d = sqrt( ((x2 - 0)*(x2 - 0)) + ((y2 - 0) * (y2 - 0)) );
return d;
}
//Allows user input and changes the point to (7,4) and displays the distance from origin.
int main()
{
int x,y;
cout << "Enter x coordinate followed by the y coordinate: " << endl;
cin >> x >> y;
Point p(x,y);
Point *newPointer = &p;
double theDistance = p.distance(x,y);
cout << "The point's distance from the origin is: " << theDistance << endl;
system("PAUSE");
}
To update coordinates of point, you need a new function -
void Point::UpdateCoordinates(int x0, int y0)
{
x = x0;
y = y0;
}
For distance(), I think you only need below.
double Point::distance()
{
return sqrt( x*x + y*y );
}