Problem: Create a vector consisting of point objects in a two-dimensional plane, calculate the average of the x and y coordinates of the point objects, and write a program that outputs the center of the points.
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
class Point
{
public:
Point(std::string pname = NULL, int px = 0, int py = 0)
{
setName(pname); setX(px); setY(py);
}
std::string getName() { return name; }
int getX() { return x; }
int getY() { return y; }
void setName(std::string pname) { name = pname; }
void setX(int px) { x = px; }
void setY(int py) { y = py; }
private:
std::string name;
int x;
int y;
};
int main()
{
int a;
int counter = 0;
cout << "number of points" << endl;
cin >> a;
vector<Point> v1(a);
while (counter < a)
{
Point p1;
string tmp;
int tmp_x;
int tmp_y;
cout << "name of point" << endl;
cin >> tmp;
p1.setName(tmp);
cout << "position of point" << endl;
cin >> tmp_x >> tmp_y;
p1.setX(tmp_x);
p1.setY(tmp_y);
v1.push_back(p1);
cout << p1.getName() <<p1.getX() << p1.getY() << endl;
}
return 0;
}
this is an example of what I want (inline is keyboard input)
Number of points: 2
Name of point: p1
position of a point: 10 20
p1 (10, 20)
Name of point: p2
position of a point: 40 50
p2 (40, 50)
centor of points :(25.0, 35.0)
How should I approach averaging?
You don't need all of those #includes.
Pay attention to NULL in class constructor.
Loop continuation condition: a--. Variable counter is redundant.
Vector is dynamic data structure. You don't need to declare its size explicitly, in this exercise. Member-function push_back will do dirty work for you.
One more extra variable p1. Try:
v1.push_back( { tmp, tmp_x, tmp_y } );
Finally...
double // if precision is necessary
total_x{}, total_y{};
for ( auto& point : v1 ) {
total_x += point.getX();
total_y += point.getY();
}
std::cout << "Average X: " << total_x / v1.size()
<< "\nAverage Y: " << total_y / v1.size();
return EXIT_SUCCESS;
Related
What should I do if I want to use the structure array flexibly?
I made my code like below, and tried Triangle and Rectangular..
Triangle was success but when i tried Rectangular I got error messages.
struct C2D {
double x, y;
};
class Polygon {
int point;
std::vector<C2D> arr;
public:
Polygon(int point_, C2D arr_[]) : arr(point_) {
point = point_;
memcpy(arr.data(), arr_, sizeof(C2D) * point);
};
void print() const {
for (int i = 0; i < point; i++) {
cout << arr[i].x << " " << arr[i].y << endl;
}
};
};
int main() {
int point;
C2D c2d[3];
cout << "point : ";
cin >> point;
cout << endl;
vector<C2D>c2d(point);
for (int i = 0; i < point; i++) {
cout << i + 1 << "x : ";
cin >> c2d[i].x;
cout << i + 1 << "y : ";
cin >> c2d[i].y;
cout << endl;
}
cout << endl;
Polygon p(point, c2d);
p.print();
return 0;
}
The problem is that you use the same name for
C2D c2d[3];
and
vector<C2D>c2d(point);
However, your code has several other issues such as using C-arrays in C++. Consider using std::vector, e.g., like this:
#include <iostream>
#include <vector>
struct C2D {
double x, y;
};
class Polygon {
std::vector<C2D> coordinates;
public:
explicit Polygon(const std::vector<C2D> &coords) : coordinates(coords) {}
void print() const {
for (const auto &c : coordinates) {
std::cout << c.x << " " << c.y << "\n";
}
}
};
int main() {
int point;
std::cout << "point : ";
std::cin >> point;
std::cout << "\n";
std::vector<C2D> coordinates(point);
for (int i = 0; i < point; i++) {
std::cout << i + 1 << "x : ";
std::cin >> coordinates[i].x;
std::cout << i + 1 << "y : ";
std::cin >> coordinates[i].y;
std::cout << "\n";
}
std::cout << "\n";
Polygon p(coordinates);
p.print();
}
As per your code, you declared variable name c2d one is C2D array type and the other is a vector of C2D what is the purpose of two variable names are the same you declared. My suggestion is to allocate c2d variable based on point count and pass to the polygon. As per my understanding change your polygon constructor with parameter array or vector and passing the corresponding argument to the constructor.
I'm trying to change a parameter of an object inside an array, but it seems like it's creating a new one when I pass it to the function.
I already saw similar questions and answers like this one, but it doesn't work for me, because I don't have a fixed array size in the final code.
I created a very short version of the code to show the problem.
#include <iostream>
using namespace std;
class Vect {
public:
Vect(int x, int y)
{
_x = x;
_y = y;
}
int _x;
int _y;
};
void ChangeX(Vect tests[], int size)
{
for (int i = 0; i < size; i++) {
tests[i]._x = 39;
}
}
int main()
{
Vect v1 = Vect(1,2);
Vect v2 = Vect(6,3);
cout << "Initial X: ";
cout << v1._x;
cout << "\n";
Vect vectors[2] = { v1, v2 };
cout << "Final X: ";
ChangeX(vectors, 2);
cout << v1._x;
return 0;
}
I expect the output to be:
Initial X: 1
Final X: 39
But in reality is:
Initial X: 1
Final X: 1
Also, using C++ vectors is not the solution for now. I'm running low on program memory usage and have a very small space for extra code.
Your issue has nothing to do with your function. It is updating the contents of the array correctly. There is no need to pass the array itself by reference.
The real problem is with the array itself. The statement Vect vectors[2] = {v1, v2}; makes copies of the v1 and v2 objects in the array. Your function is modifying the copies, and then afterwards you output values from the originals instead of the copies. So, your output does not change, since the function is not modifying the originals.
To accomplish what you are attempting, pass in an array of pointers instead, where the pointers are pointing at the original objects, not copies of them, eg:
#include <iostream>
class Vect {
public:
Vect(int x, int y){
_x = x;
_y = y;
};
int _x;
int _y;
};
void ChangeX(Vect* tests[], int size){
for(int i = 0; i < size; i++){
tests[i]->_x = 39;
}
}
int main()
{
Vect v1(1,2);
Vect v2(6,3);
std::cout << "Initial X:\n";
std::cout << v1._x << "\n";
std::cout << v2._x << "\n";
Vect* vectors[2] = {&v1, &v2};
ChangeX(vectors, 2);
std::cout << "Final X:\n";
std::cout << v1._x << "\n";
std::cout << v2._x << "\n";
return 0;
}
Live Demo
Otherwise, start out with an array to begin with, eg:
#include <iostream>
class Vect {
public:
Vect(int x, int y){
_x = x;
_y = y;
};
int _x;
int _y;
};
void ChangeX(Vect tests[], int size){
for(int i = 0; i < size; i++){
tests[i]._x = 39;
}
}
int main()
{
Vect vectors[2] = {Vect(1,2), Vect(6,3)};
std::cout << "Initial X:\n";
std::cout << vectors[0]._x << "\n";
std::cout << vectors[1]._x << "\n";
ChangeX(vectors, 2);
std::cout << "Final X:\n";
std::cout << vectors[0]._x << "\n";
std::cout << vectors[1]._x << "\n";
return 0;
}
Live Demo
I have been trying to print the points like The position of the point is (1,2) from using class, but I can't figure out a way to do it. I simply can't find a way to return two numbers like that, but the problem requires solution that way.
#include <iostream>
using namespace std;
class MyPoint{
public:
int x,y,radius;
MyPoint()
{
x=0;
y=0;
}
MyPoint(int x1,int y1)
{
x=x1;
y=y1;
}
int point_display()
{
char st=(x,y);
return st;
}
int getAdd()
{
return x+y;
}
};
int main()
{
MyPoint mypoint;
cin>>mypoint.x>>mypoint.y;
cout<<"The position of the point is "<<mypoint.point_display()<<endl;
cout<<"The sum of the coordinates is "<<mypoint.getAdd()<<endl;
return 0;
}
The usual solution to this is to provide an overload of operator << for class MyPoint to print the point.
Something like this:
#include <iostream>
using namespace std;
class MyPoint{
public:
int x,y,radius;
MyPoint()
{
x=0;
y=0;
}
MyPoint(int x1,int y1)
{
x=x1;
y=y1;
}
int getAdd()
{
return x+y;
}
friend ostream& operator << (ostream& os, const MyPoint& p);
};
ostream& operator << (ostream& os, const MyPoint& p)
{
os << p.x << ", " << p.y;
return os;
}
int main()
{
MyPoint mypoint { 1,2 };
cout<<"The position of the point is "<<mypoint<<endl;
cout<<"The sum of the coordinates is "<<mypoint.getAdd()<<endl;
return 0;
}
Output:
The position of the point is 1, 2
The sum of the coordinates is 3
Live demo
Your point_display could return a string composed of the 2 values:
std::string point_display()
{
return std::string{"("} + std::to_string(x)
+ "," + std::to_string(x) + ")";
}
Alternatively, as your question asks about returning 2 values, the function could return a pair:
std::pair<int,int> point_display ()
{
return {x,y};
}
and in main, you could do:
auto [x, y] = mypoint.point_display();
cout << "The position of the point is ("
<< x << "," << y << ")" << endl;
However, since the data members are public, you could just destructure the object and print out the values in main:
auto [x, y, radius] = mypoint;
cout << "The position of the point is ("
<< x << "," << y << ")" << endl;
If all you want to do is print the coordinates, you could have the method do it:
void point_display()
{
cout << "(" << x << ", " << y << ")";
}
...
cout<<"The position of the point is ";
mypoint.point_display();
cout << endl;
If you really want to return the coordinates, you could have separate accessors ("getters"):
int getX()
{
return x;
}
int getY()
{
return y;
}
or use references:
void getCoordinates(int &rx, int &ry)
{
rx = x;
ry = y;
}
...
int a, b;
mypoint.getCoordinates(a, b);
cout << a << " " << b << endl;
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I recently started learning C++. Today i wanted to make a demo "Player" class which has x and y positions.
I'm not sure if my method is correct or not but what I'm worried about is when i print (x , y) int the end it gets printed as (y,x).
Player.h :
#pragma once
#include <string>
#include <iostream>
// CLASS -----------------------------------------------------------------
class Player {
private :
std::string name;
float x, y;
const int SPEED = 5;
public:
Player() : x(0) , y(0) {
}
float* getX() {
return &x;
}
float* getY() {
return &y;
}
std::string getName() {
return name;
}
void setX(float block) {
x = block;
}
void setY(float block) {
y = block;
}
void move( float* axis , int direction) {
*axis += direction * SPEED;
}
void setName(std::string block) {
name = block;
}
};
//------------------------------------------------------------------------
std::string getInput(std::string value) {
std::string temp;
std::cout << "Enter "<< value <<" : ";
std::cin >> temp;
std::cout << std::endl;
return temp;
}
Player.cpp :
#include "Player.h"
int main() {
Player p1;
std::string axis;
int dir;
float* yAxis = p1.getY();
float* xAxis = p1.getX();
p1.setName(getInput("name"));
std::cout << "Your name is " << p1.getName() << std::endl;
std::cout << "Enter 'y' to move in y axis , 'x' to move in x axis : ";
std::cin >> axis;
std::cout << "Enter a positive / negative value for the direction";
std::cin >> dir;
if (axis.compare("y")) {
if (dir < 0) {
p1.move(yAxis, -1);
}
else {
p1.move(yAxis, 1);
}
}
else if (axis.compare("x")) {
if (dir < 0) {
p1.move(xAxis, -1);
}
else {
p1.move(xAxis, 1);
}
}
std::cout << "Position ( " << *xAxis << " , " << *yAxis << " )" << std::endl;
getInput("anything to exit");
}
Can someone answer where I'm going wrong?
std::string::compare returns 0 if the strings are equal!
This is the opposite way to how you are expecting.
Replacing with axis == "y" &c. would be more readable, although there are better ways of achieving this from a performance perspective.
I just wonder if all virtual function has got to be a const?
I'm having some issue with them as the area always return 0 for my square when ever i wanna print them out. would appreciate if someone could enlighten me.
shapetwod.h
class ShapeTwoD
{
protected:
string name, warpSpace;
bool containsWarpSpace;
public:
//constructor
ShapeTwoD();
ShapeTwoD(string, bool);
//accessors/set function
void setName(string);
//mutator/get function
string getName();
//methods
virtual double computeArea();
virtual void view();
};
shapetwod.cpp
ShapeTwoD::ShapeTwoD()
{
string name = "";
}
ShapeTwoD::ShapeTwoD(string ShapeName)
{
name = ShapeName;
}
void ShapeTwoD::setName(string shapeName)
{
name=shapeName;
}
string ShapeTwoD::getName()
{
return name;
}
double ShapeTwoD::computeArea()
{
return 0;
}
void ShapeTwoD::view()
{
cout << "Area is: " << endl;
}
square.h
class Square:public ShapeTwoD
{
private:
int xVal,yVal;
int length, breath;
double area;
public:
Square();
Square(string, int, int, double);
//acessor method
//int getSquareDetails();
int getxCord();
int getyCord();
double getArea();
virtual double computeArea();
void view();
int xvalue[4];
int yvalue[4];
};
square.cpp
Square::Square()
{
xVal = 0;
yVal = 0;
area = 0;
}
Square::Square(string ShapeName, bool warpspace, int xval, int yval, double areas):ShapeTwoD(ShapeName, warpspace)
{
xVal = xval;
yVal = yval;
area = areas;
}
void Square::setSquareCord()
{
for (int i=0; i<4; i++)
{
cout << "Please enter x-ordinate of pt " << i+1 << ": ";
cin >> xVal;
xvalue[i] = xVal;
cout << endl;
cout << "Please enter y-ordinate of pt " << i+1 << ": ";
cin >> yVal;
yvalue[i] = yVal;
cout << endl;
}
}
double Square::computeArea()
{
int xmax = xvalue[1];
int xmin = xvalue[1];
int ymax = yvalue[1];
int ymin = yvalue[1];
for(int i=0; i<4; i++)
{
if(xvalue[i]>xmax)
{
xmax = xvalue[i];
}
else if(xvalue[i]<xmin)
{
xmin = xvalue[i];
}
}
for(int i=0; i<4; i++)
{
if(yvalue[i]>ymax)
{
ymax = yvalue[i];
}
else if(yvalue[i]<ymin)
{
ymin = yvalue[i];
}
}
length = xmax - xmin;
breath = ymax - ymin;
area = length * breath;
return (area);
}
int Square::getxCord()
{
return xVal;
}
int Square::getyCord()
{
return yVal;
}
double Square::getArea()
{
return area;
}
void Square::view()
{
cout << "Name: " << getName() << endl;
cout << "Area is: " << area << endl;
}
Sorry but I don't really know how to phase my question. i'm actually using Polymorphism &
Virtual Functions here and my computeArea and view function are virtual.
so in my square.cpp under the "view" function the programme would always return me 0 and i'm not sure why is this so..
this is how i call the view function. not sure if it's helping here..
void Shape2DLink::InputSensor()
{
string shape,type;
cout<<endl<<"\n"<<"[ Input sensor data ]"<<endl;
cout << "Please enter name of shape: " << endl;
cin >> shape;
shape2D.setName(shape);
cout << "Please enter special type : " << endl;
cin >> type;
shape2D.setWarpSpace(type);
if(shape == "Square")
{
square.setSquareCord();
square.computeArea();
square.isPointOnShape();
square.isPointInShape();
Square *mySquare = new Square;
shapeobject.push_back(mySquare);
//shapeobject.push_back( new Square );
}
}
void Shape2DLink::Display()
{
vector<ShapeTwoD*>::iterator vectorIt = shapeobject.begin();
while(vectorIt != shapeobject.end())
{
(*vectorIt)->view();
vectorIt++;
}
}
I just wonder if all virtual function has got to be a const?
No.
I'm having some issue with them as the area always return 0 for my
square when ever i wanna print them out.
Hmm, ok, let's take a look.
double ShapeTwoD::computeArea()
{
return 0;
}
Yup, uh-huh.
I've got my Magic Monkey Hat on, and I predict that the problem you're having is caused by Object Slicing. Consider:
void foo (Shape2D shape)
{
cout << shape.compute_area() << "\n"
}
int main()
{
Square sq;
foo (sq);
}
Since foo above takes a Shape2D by-value, all the Squareness of whatever is passed to it is sliced away, leaving only a Shape2D. Of course since Shape2D::compute_area just returns 0, that's what is computed.
To fix this particular problem, don't copy the object or take it by-value, but take it by-reference instead:
void foo (Shape2D& shape)
{
cout << shape.compute_area() << "\n"
}
Now the object isn't sliced.
Look for similar problems in the code you haven't shown us.
No a virtual method may or may not be const. Your problem is somewhere else, but not in the code you have included.