#include <iostream>
#include "Shapes.h"
int main()
{
//variables
int height = 0;
int width = 0;
Rectangle rect = Rectangle();
Triangle tran = Triangle();
Square sqar = Square();
std::cout << "What is the width of the shape? ";
std::cin >> width;
std::cout << "What is the height of the shape?";
std::cin >> height;
rect.set_lengths(width, height);
std::cout << "If the shape is a triangle, the area is " << tran.area() << "." << std::endl;
std::cout << "If the shape is a rectangle, the area is " << rect.area() << "." << std::endl;
std::cout << "If the shape is a square, the area is " << sqar.areaByWidth() << " by the width value," << std::endl;
std::cout << "and " << sqar.areaByHeight() << " by the height value." << std::endl;
system("pause");
}
Header file:
//Our base class
class Shape
{
protected:
int width, height, shapes = 0;
public:
void set_lengths(int width, int height)
{
width = width; height = height;
}
};
//Rectangle is a shape
class Rectangle : public Shape
{
public:
Rectangle()
{
std::cout << "Created a rectangle!\n";
shapes = shapes + 1;
}
~Rectangle()
{
shapes = shapes - 1;
}
int area()
{
return width * height;
}
};
//Triangle is a shape
class Triangle : public Shape
{
public:
Triangle()
{
shapes = shapes + 1;
std::cout << "Created a triangle!\n";
}
~Triangle()
{
shapes = shapes - 1;
}
int area()
{
return width * height / 2;
}
};
//Square is a shape
class Square : public Shape
{
public:
Square()
{
shapes = shapes + 1;
std::cout << "Created a square!";
}
~Square()
{
shapes = shapes - 1;
}
int areaByWidth()
{
return width * width;
}
int areaByHeight()
{
return height * height;
}
};
When I set the values, it works fine (shows the correct value in visual studio debugger), but when I call area() it brings back -846388729 or something similiar? Why is the value being reset? I have been banging my head against a wall for hours on this. Seems like a common problem to noobies like myself but I'm not understanding the other solutions on here :(
The function set_lengths did not set the member variable correctly, just set the value back to the function arguments.
change
void set_lengths(int width, int height)
{
width = width; height = height;
}
to
void set_lengths(int width, int height)
{
this->width = width; this->height = height;
}
Or change the name of the member variables for a good habit:
int width_, height_, shapes_;
void set_lengths(int width, int height)
{
width_ = width;
height_ = height;
}
Becuase width and height are not initilized.
Change the line to:
int i = 0, j = 0, k = 0;
Also, you're only setting the dimension of the rect object, not the triangle or the square.
Related
I'm trying to build a gamengine, and I need to sort characters and rooftiles based on the y-coordinate of their feet before drawing them, so that folk/tiles infront are drawn ontop of folk/tiles behind them. I've gotten it to work with just characters, but I need rooftiles as well.
the classes are both children of renderable, and share some data. The classes are forward-declared, and there are global lists g_entities, g_tiles, and g_renderable.
class renderable {
public:
float x;
float y;
float width;
float height;
SDL_Surface* image;
SDL_Texture* texture;
void render(SDL_Renderer * renderer, camera fcamera) {
rect obj(floor((x -fcamera.x)* fcamera.zoom), floor((y-fcamera.y)* fcamera.zoom), floor(width *fcamera.zoom), floor(height * fcamera.zoom));
rect cam(0, 0, fcamera.width, fcamera.height);
if(RectOverlap(obj, cam)) {
SDL_Rect dstrect = { (x -fcamera.x)* fcamera.zoom, (y-fcamera.y)* fcamera.zoom, width *fcamera.zoom, height * fcamera.zoom};
SDL_RenderCopy(renderer, texture, NULL, &dstrect);
}
}
};
class entity: public renderable {
public:
float x;
float y;
float xagil;
float yagil;
//... other stuff, including image and texture
void render(SDL_Renderer * renderer, camera fcamera);
};
class tile: public renderable {
public:
int x;
int y;
int z = 0; //represents layer. 0 default
float width;
float height;
//... other stuff, including image and texture
void render(SDL_Renderer * renderer, camera fcamera);
};
The list is created when the map is loaded with
for (int i = 0; i < g_entities.size(); i++) {
g_renderable.push_back(g_entities[i]);
}
for (int i = 0; i < g_tiles.size(); i++) {
if(g_tiles[i]->z ==2) {
g_renderable.push_back(g_tiles[i]);
g_tiles.erase(g_tiles.begin() + i);
i--;
}
}
And then in main I planned to sort the g_renderable array instead of the g_entities array and have everything snug, but instead I get a SIGFAULT. I tracked down the problem with GDB and it turns out that g_renderable[] isnt getting informed with the attributes of g_entities[] (and probly not g_tiles[] either).
This is what I mean:
g_renderable.clear();
g_renderable.reserve(g_entities.size() + g_tiles.size()); // preallocate memory
cout << "g_entities.size" <<g_entities.size() << endl;
cout << "g_entities.size" <<g_entities.size() << endl;
cout << "g_entities height " << g_entities[0]->height << endl; //couts 122
for (int i = 0; i < g_entities.size(); i++) {
g_renderable.push_back(g_entities[i]);
}
cout << "g_renderable height " << g_renderable[0]->height << endl; //couts 0
for (int i = 0; i < g_tiles.size(); i++) {
if(g_tiles[i]->z ==2) {
g_renderable.push_back(g_tiles[i]);
g_tiles.erase(g_tiles.begin() + i);
i--;
}
}
Why doesnt my vector return the member data as expected?
I am trying to create RGB image in C++. I am not using any image libraries like OpenCv.
Firstly, I tried to create grayscale image. I want to draw rectangle to image. I am giving parameters at function like starting points, width, height etc. This code lines are working good for this grayscale challenge but I am trying to increase color channels to 3 like RGB. Then, I am setting Red, Green and Blue values but it is not working. This is my problem.
How can I work correctly?
x => starting point where x coordinate
y => starting point where y coordinate
width => rectangle width
height => rectangle height
value => RGB or Grayscale color value
My codes
Image::Image(int width, int height, int n_channels, int step)
{
cout << "Image constructor is running!" << endl;
m_width = width;
m_height = height;
m_n_channels = n_channels;
m_step = m_width*m_n_channels;
if (m_step < step)
m_step = step;
m_data = new uchar[m_step*height];
}
Image* Image::new_gray(int width, int height)
{
cout << "New gray image is creating!" << endl;
return new Image(width, height, 1);
}
Image* Image::new_rgb(int width, int height)
{
cout << "New RGB image is creating!" << endl;
return new Image(width, height, 3);
}
void Image::set_rect(int x, int y, int width, int height, uchar value)
{
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}
for (int j = y; j < y+height; ++j) {
if (j >= m_height)
break;
uchar* row_data = data(j);
for (int i = x; i < x+width; ++i) {
if (i >= m_width)
break;
for (int c = 0; c < m_n_channels; ++c)
if (c == 0) {
row_data[i*m_n_channels + c] = value;
} else if (c == 1) {
row_data[i*m_n_channels + c] = value;
} else if (c == 2) {
row_data[i*m_n_channels + c] = value;
}
}
}
}
bool Image::write_pnm(const std::string& filename) const
{
if (m_n_channels != 1) {
const string magic_head = "P6";
ofstream fout;
string extended_name = filename + ".ppm";
fout.open(extended_name.c_str(), ios::out | ios::binary);
fout << magic_head << "\n";
fout << m_width << " " << m_height << " 255\n";
for (int y = 0; y < m_height; ++y) {
const uchar *row_data = data(y);
cout << reinterpret_cast<const char*>(row_data);
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar));
}
fout.close();
return true;
}
const string magic_head = "P5";
ofstream fout;
string extended_name = filename + ".pgm";
fout.open(extended_name.c_str(), ios::out | ios::binary);
fout << magic_head << "\n";
fout << m_width << " " << m_height << " 255\n";
for (int y = 0; y < m_height; ++y) {
const uchar *row_data = data(y);
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar));
}
fout.close();
return true;
}
My main function
#include <cstdlib>
#include <iostream>
#include "image.h"
using std::cout;
using std::endl;
using ceng391::Image;
int main(int argc, char** argv)
{
Image* gray = Image::new_gray(128, 128);
cout << "(" << gray->w() << "x" << gray->h() << ") channels: "
<< gray->n_ch() << " step: " << gray->step() << endl;
gray->set_zero();
gray->set_rect(32, 32, 64, 64, 255);
gray->write_pnm("/tmp/test_image");
Image* rgb_image = Image::new_rgb(128,128);
cout << "(" << rgb_image->w() << "x" << rgb_image->h() << ") channels: "
<< rgb_image->n_ch() << " step: " << rgb_image->step() << endl;
rgb_image->set_zero_rgb();
rgb_image->set_rect(32, 32, 64, 64, 150);
rgb_image->write_pnm("/tmp/test_image_rgb");
delete gray;
delete rgb_image;
return EXIT_SUCCESS;
}
This code is working for grayscale images because grayscale images have same number of pixels with width.
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar));
But when I wanted to save RGB images, increased number of pixels 3 times. One pixel respresents via 3 channels so need to multiply stream size with 3 (R,G,B channels) for one pixel.
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar)*3);
I'm writing a class rectangle for this assignment Create a class Rectangle with attributes length and width, each of which defaults to 1. Provide member functions that calculate the perimeter and the area of the rectangle. Also, provide set and get functions for the length and width attributes. The set functions should verify that length and width are each floating-point numbers larger than 0.0 and less than 20.0.
I keep getting an error advising setLengthandWidth, setLength, and setWidth must return a value. I'm not sure where I'm going wrong. Any advice? Here are my 3 files.
Header file
#ifndef Rectangle_H
#define Rectangle_H
class Rectangle
{
public:
Rectangle();
Rectangle(float length);
Rectangle(float length, float width);
~Rectangle();
float setLengthAndWidth(float, float);
float setLength(float Length);
float setWidth(float Width);
float calculatePerimeter();
float calculateArea();
void printInfo();
float getLength();
float getWidth();
private:
float length;
float width;
float area;
float perimeter;
};
#endif#pragma once
main.cpp file
#include <iostream>
#include <iomanip>
#include <cmath>
#include "Rectangle.h"
using namespace std;
int main()
{
Rectangle objectOne;
Rectangle objectTwo(7.1, 3.2);
Rectangle objectThree(6.3);
Rectangle objectFour(200, 300);
Rectangle objectFive = objectTwo;
cout << "The first objects information is\n ";
objectOne.printInfo();
cout << "The second objects information is\n ";
objectTwo.printInfo();
cout << "The third objects information is\n ";
objectThree.printInfo();
cout << "The fourth objects information is\n ";
objectFour.printInfo();
cout << "The fifth objects information is\n ";
objectFive.printInfo();
}
member .cpp file
#include <iostream>
#include <iomanip>
#include <cmath>
#include "Rectangle.h"
using namespace std;
Rectangle::Rectangle()
{
length = width = 1.0;
}
Rectangle::Rectangle(float length)
{
setLengthAndWidth(length, 1.0);
}
Rectangle::Rectangle(float length, float width)
{
setLengthAndWidth(length, width);
}
float Rectangle::setLengthAndWidth(float Len, float Wid)
{
setLength(Len);
setWidth(Wid);
}
float Rectangle::setLength(float length)
{
if (length >= 0 || length <= 20.0)
length = length;
else
length = 1.0;
}
float Rectangle::setWidth(float width)
{
if (width >= 0 || width <= 20.0)
width = width;
else
width = 1.0;
}
float Rectangle::calculatePerimeter()
{
perimeter = (length * 2) + (width * 2) ;
return perimeter;
}
float Rectangle::calculateArea()
{
area = length * width;
return area;
}
float Rectangle::getLength()
{
cout << "Please enter length" << endl;
cin >> length;
return length;
}
float Rectangle::getWidth()
{
cout << "Please enter width" << endl;
cin >> width;
return width;
}
void Rectangle::printInfo()
{
cout << "the length is " << length << endl << "the width is " << width << endl;
cout << "the perimeter is " << perimeter << endl << "the area is " << area << endl;
}
Rectangle::~Rectangle()
{
cout << "the object has gone out of scope. ";
}
In the declaration and definition of setLengthandWidth, setLength, and setWidth methods, you specify that they return a float data type :
//In header
float setLengthAndWidth(float, float);
float setLength(float Length);
float setWidth(float Width);
//In CPP file
float Rectangle::setLengthAndWidth(float Len, float Wid)
{
setLength(Len);
setWidth(Wid);
}
float Rectangle::setLength(float length)
{
if (length >= 0 || length <= 20.0)
length = length;
else
length = 1.0;
}
float Rectangle::setWidth(float width)
{
if (width >= 0 || width <= 20.0)
width = width;
else
width = 1.0;
}
If you want to not get that error, change the data type from float to void in the method declaration and definitions, like this :
//In header
void setLengthAndWidth(float, float);
void setLength(float Length);
void setWidth(float Width);
//In CPP file
void Rectangle::setLengthAndWidth(float Len, float Wid)
{
setLength(Len);
setWidth(Wid);
}
void Rectangle::setLength(float length)
{
if (length >= 0 || length <= 20.0)
length = length;
else
length = 1.0;
}
void Rectangle::setWidth(float width)
{
if (width >= 0 || width <= 20.0)
width = width;
else
width = 1.0;
}
Why does your getLength and getWidth methods modify values? Generally accessor methods are only supposed return the appropriate fields.
HatsuPointerKun is correct though.
The methods have a return type of float but fail to return any value.
Either have them return a float number (most likely whatever you set them to) or change the return type to void.
I have written some code using a class that will display the measurements of a box. I am doing so by having the output in a toString() method and it appears to be working but when i run the program I get the following error:
Height: 1 Width: 1 Depth: 1terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Then the program chrashes. Also I've noticed that the program doesn't display the volume after the 3 dimensions.
Here is the code:
#include <iostream>
#include <iomanip> // for output formatting
#include <stdexcept> // for out_of_range
#include <sstream> // for stringstream
#include <string>
#include <cstdlib> // for system()
using namespace std;
class Box
{
public:
// Constructors
Box(double height=1, double width=1, double depth=1);
// Mutators
void setHeight(double height);
void setWidth(double width);
void setDepth(double depth);
// Accessors
double getHeight() const {return (boxHeight);};
double getWidth() const {return (boxWidth);};
double getDepth() const {return (boxDepth);};
double getVolume() const;
string toString() ;
private:
double boxHeight;
double boxWidth;
double boxDepth;
double boxVolume;
};
int main()
{
cout << "\nBox Mesurement!";
cout << "\n===============";
cout << endl;
Box boxDem(true);
// WHERE THE STRING IS DISPLAYED
cout << "\n" << boxDem.toString();
cout<< endl;
cout << "\n" << boxDem.getVolume();
return 0;
}
Box::Box(double height, double width, double depth)
{
setHeight(height);
setWidth(width);
setDepth(depth);
}
void Box::setHeight(double height)
{
const double MIN = 0.01;
if (height > 0 && height < MIN)
{
height = 0.01;
boxHeight = height;
}
else if (height < 0)
{
height *= -1;
boxHeight = height;
}
else
{
boxHeight = height;
}
}
void Box::setWidth(double width)
{
const double MIN = 0.01;
if (width > 0 && width < MIN)
{
width = 0.01;
boxWidth = width;
}
else if (width < 0)
{
width *= -1;
boxWidth = width;
}
else
{
boxWidth = width;
}
}
void Box::setDepth(double depth)
{
const double MIN = 0.01;
if (depth > 0 && depth < MIN)
{
depth = 0.01;
boxDepth = depth;
}
else if (depth < 0)
{
depth *= -1;
boxDepth = depth;
}
else
{
boxDepth = depth;
}
}
double Box::getVolume() const
{
double volume = 0.0;
volume = getHeight() * getHeight() *getDepth();
return volume;
}
// WHERE THE PROBLEM IS
string Box::toString()
{
cout << "Height: " << getHeight() << " Width: " << getWidth() << " Depth: " << getDepth();
return 0;
}
cout is meant to output stuff to the command line, but you are writing a function that's supposed to return a string, that makes little sense.
ostringstream is a neat class that allows you to build strings using the same mechanisms as cout, try this:
string Box::toString()
{
std::ostringstream result;
result << "Height: " << getHeight() << " Width: " << getWidth() << " Depth: " << getDepth();
return result.str();
}
I'm trying to calculate the area of the circle and the rectangle by using the existing data (radius ,width, and height). But i have some errors, i hope you can help me fix it.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Shape
{
public:
virtual void Draw () = 0;
virtual void MoveTo (int newx, int newy) = 0;
virtual int GetArea()const = 0;
};
class Rectangle : public Shape
{
public:
Rectangle (int x, int y, int w, int h);
virtual void Draw ();
virtual void MoveTo (int newx, int newy);
int GetArea() {return height * width;}
private:
int x, y;
int width;
int height;
};
void Rectangle::Draw ()
{
cout << "Drawing a Rectangle at (" << x << "," << y
<< "), width " << width << ", height " << height << "\n";
};
void Rectangle::MoveTo (int newx, int newy)
{
x = newx;
y = newy;
}
Rectangle::Rectangle (int initx, int inity, int initw, int inith)
{
x = initx;
y = inity;
width = initw;
height = inith;
}
class Circle : public Shape
{
public:
Circle (int initx, int inity, int initr);
virtual void Draw ();
virtual void MoveTo (int newx, int newy);
int GetArea() {return 3.14 * radius * radius;}
private:
int x, y;
int radius;
};
void Circle::Draw ()
{
cout << "Drawing a Circle at (" << x << "," << y
<< "), radius " << radius <<"\n";
}
void Circle::MoveTo (int newx, int newy)
{
x = newx;
y = newy;
}
Circle::Circle (int initx, int inity, int initr)
{
x = initx;
y = inity;
radius = initr;
}
int main ()
{
Shape * shapes[2];
shapes[0] = new Rectangle (10, 20, 5, 6);
shapes[1] = new Circle (15, 25, 8);
for (int i=0; i<2; ++i) {
shapes[i]->Draw();
shapes[i]->GetArea();
}
return 0;
}
Rectangle::GetArea method should be const. You declared it non-const, so it is not considered an override of Shape::GetArea, so Rectangle is considered abstract.
You may want to rethink your return type too.
int Circle::GetArea() {return 3.14 * radius * radius;}
As pointed by #Cătălin Pitiș, the GetArea() methods in derived classes need to be const. Otherwise compiler will complain that you have not provided the implementation for pure virtual functions (hence the derived classes become abstract) and will not allow you to create objects of the. Additionally, you need to declare a virtual destructor for Shape class. Otherwise, you will not be able release the memory properly. Also, you are not releasing the memory in main() function. You should use delete to release the memory allocated for the objects.