Unable to change private variables using member functions - c++

#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

Related

Calculating distance between to points of a triangle using pointers

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...

2D Poisson-disk sampling in a specific square (not a unit square) with specific minimum distance

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.

how do i use the pointer variable to change the value

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

Returning a boolean value from a Circle Class C++

I am trying to return a boolean value using a C++ class. It needs to be able to check whether circle A is the same size as circle B using an overload operator > which I have added as a public member in the class. In my int main it always seems to return false even when the circles are the same size.
Thanks, in advance.
Circle class:
#include <iostream>
#include <cmath>
using namespace std;
//creating a constant pi that can't be changed
const double pi = 3.14159265;
class Circle
{
//defining the private memeber variables
private:
double radius, xpos, ypos;
//defining the public member variables
public:
//creating a constructor that takes all of the variables
Circle(double r, double xposition, double yposition) {
radius = r;
xpos = xposition;
ypos = yposition;
}
//creating a constructor that takes just the radius
Circle(double r) {
radius = r;
xpos = 0;
ypos = 0;
}
//creating a contructor that initialised everything to 0
Circle() {
radius = 0;
xpos = 0;
ypos = 0;
}
//defining the functions for radius, X-position, Y-position and area
double getRadius() {return radius;}
double getX() {return xpos;}
double getY() {return ypos;}
double getArea() {return pi*radius*radius;}
//creating an overaload operator + to add the various properties of a circle together
Circle operator+(Circle C) {
radius = sqrt(this->getRadius()*this->getRadius() + C.getRadius()*C.getRadius()); //calculates the radius from the area
xpos = (this->getX() + C.getX()) / 2.; //calculating the half way x position
ypos = (this->getY() + C.getY()) / 2.; //calculating the half way y position
return Circle(radius, xpos, ypos);
}
//created an overload operator << that outputs information about the circle in a consistent manor
friend ostream& operator<<(ostream& os, Circle C) {
return os << "radius = " << C.getRadius() << " at (x,y) = (" << C.getX() << "," << C.getY() << ")";
}
bool operator>(Circle C) {
if (this->getRadius() > C.getRadius()) {
return true;
}
else {
return false;
}
}
};
Int main ()
#include "Circle.hpp"
using namespace std;
int main()
{
//defining the circles A and B
Circle A(4.0,2.0,1.0);
cout << "Circle A: " << A << endl;
Circle B(4.0,5.0,6.0);
cout << "Circle B: " << B << endl;
//Adds A and B using the overload operator +
Circle C = A + B;
//Outputs the formatted text using the overload operator <<
cout << "Circle C: " << C << endl;
bool test;
Circle D(4.0,2.0,1.0);
if (A > D) {
test = false;
}
else if (D > A) {
test = false;
}
else {
test = true;
}
cout << boolalpha << test << endl;
return 0;
}
A.r is 4.0. D.r is also 4.0. Neither D > A nor A > D is true. > checks for real greater than. If you want to have greater-or-equal use >= instead.
When you do the following you are changing the value of A's radius
Circle C = A + B
"In my int main it always seems to return false even when the circles are the same size"
It will surely return false when circle are of same size as your condition is:-
if ( this->getRadius() > C.getRadius() )
return true;
everything other than this would return false. If you want to return true when your circle are of same size then make it:-
if ( this->getRadius() < C.getRadius() )
return false;
else
return true;
EDITED IN RESPONSE TO COMMENT:-
Then probably you can use enum if want to to test three different scenarios:-
if ( this->getRadius() > C.getRadius() )
return ENUM_GREATER;
else if ( this->getRadius() == C.getRadius() )
return ENUM_EQUAL;
return ENUM_LESSER;
Your operator+ modifies the left-hand operand. So, this line modifies A :
Circle C = A + B;
(including the radius member). So, by the time you compare A to D, A's radius is no longer 4.0.
The operator+ can be modified as follows to fix this :
Circle operator+(const Circle& C) const {
double r = sqrt(this->getRadius()*this->getRadius() + C.getRadius()*C.getRadius()); //calculates the radius from the area
double x = (this->getX() + C.getX()) / 2.; //calculating the half way x position
double y = (this->getY() + C.getY()) / 2.; //calculating the half way y position
return Circle(r, x, y);
}

Was not declared in this scope issue

I'm checking to see and understand someone else's code... The code worked in his computer, however when I tried to edit it in mine, it doesn't seem to work. The lib files are all connected properly thou...
#include "play.h"
#include "Lib110ct/Lib110ct.h"
#include <ctime>
int main(int argc, char** argv)
{
Win110ct win;
Turtle * t = win.getTurtle();
win.hideTurtle();
const int NumOfBook = 7;
Player You(512,384);
Book B[NumOfBook];
int pts = 0;
char in;
time_t ti;
while (in != 'x')
{
for (int i = 0; i<NumOfBook; i++)
{
if (A[i].isReadBy(You))
{
B[i].setPosition(rand() % 1024 + 1,rand() % 768 + 1);
pts++;
}
B[i].move();
B[i].draw(t);
}
You.draw(t);
win << "Points: " << pts << "\n";
win.render();
win.setPosition(-1,-1);
in = win.getchar();
win.clearBack();
win.clear();
win.setPosition(0,0);
if (in == 'w')
You.moveRelative(0,-50);
else if (in == 's')
You.moveRelative(0,50);
else if (in == 'a')
You.moveRelative(-50,0);
else if (in == 'd')
You.moveRelative(50,0);
}
return 0;
}
However I run into the error... "Book" was not declared in this scope.
The header play.h file's code is as follows..
#include "Lib110ct/Lib110ct.h"
#include <cstdlib>
//Player class, used to create the controllable character.
class Player
{
protected:
double xpos, ypos;
public:
Player(){};
//constructor, user input variables stored as xpos and ypos, then player is drawn
Player(double x, double y)
{
xpos = x;
ypos = y;
}
//draws the new position of the turtle
void draw(Turtle* t)
{
t->setPosition(xpos,ypos);
t->penDown();
for (int i = 0; i < 180; i++ )
{
t->turn(2);
t->moveForward(1);
}
}
double getX(){ return xpos; } //returns the x position of the player
double getY(){ return ypos; } //returns the y position of the player
//moves the player by x increment and y increment (leave x or y as 0 to not move along the respective axis)
//relative to current position
void moveRelative(double xadd, double yadd)
{
if (xpos+xadd > 0 && xpos+xadd < 1024 && ypos+yadd > 0 && ypos+yadd < 768)
{
xpos += xadd;
ypos += yadd;
}
}
};
//Food class. Not controlled by player
class Food
{
protected:
double xpos, ypos, xdir, ydir;
public:
//constructor, random x and y co-ordinates stored as xpos and ypos. food is drawn in those co-ordinates
//random xdir and ydir, food initially moves in this direction
Food()
{
xpos = rand() % 1024 + 1;
ypos = rand() % 768 + 1;
xdir = rand() % 41 - 20;
ydir = rand() % 41 - 20;
}
//draws the food
void draw(Turtle* t)
{
t->setPosition(xpos,ypos);
t->penDown();
for (int i = 0; i < 4; i++ )
{
t->turn(90);
t->moveForward(20);
}
}
double getX(){ return xpos; } //returns the x position of the player
double getY(){ return ypos; } //returns the y position of the player
//moves the food to a specific location, not relative to current position
void setPosition(double x,double y)
{
xpos = x;
ypos = y;
}
//moves the food in the specified directions, given by the variables xdir and ydir
void move()
{
if (!(xpos+xdir>0 && xpos+xdir<1024 && ypos+ydir>0 && ypos+ydir<768))
{
xdir = -xdir;
ydir = -ydir;
}
xpos += xdir;
ypos += ydir;
}
//returns TRUE if the player is in a close proximity to the food, otherwise false
bool isEatenBy(Player Play)
{
double pX = Play.getX();
double pY = Play.getY();
double fX = getX();
double fY = getY();
return pX+60>fX && pX-20<fX & pY+40>fY && pY-40<fY;
}
};
You are trying to use an array of type 'Book', which is probably a class you intended to define:
Book B[NumOfBook];
However, you have not defined this in the code you posted above, or in the code you put in Dropbox.
Either add a definition for class Book to play.h, or create a new header file, perhaps called book.h, with the definition and then #include "book.h" in your cpp file. Your Book class will need methods to setPosition, move and draw.