So here is my code:
//Shapes.cpp
#include <cassert>
#include <cmath>
#include "shapes.h"
using namespace std;
const double PI = 3.14159;
////////////////////////// Ellipse //////////////////////////
Ellipse::Ellipse() : xRad(0), yRad(0){}
Ellipse::Ellipse(double xRad_in, double yRad_in)
: xRad(xRad_in), yRad(yRad_in) {}
double Ellipse::area() const {
return PI * xRad * yRad;
}
void Ellipse::draw(Canvas *canvas) const{
// Iterate through the grid of (x,y) pixel coordinates
// in the canvas.
for(int x = 0; x < CANVAS_WIDTH; ++x){
for(int y = 0; y < CANVAS_HEIGHT; ++y){
// The ellipse contains the point (x,y) if and only if
// ((x-xPos)/xRad)^2 + ((y-yPos)/yRad)^2 <= 1
double xDiff = x - get_xPos();
double yDiff = y - get_yPos();
if( (xDiff/xRad)*(xDiff/xRad) + (yDiff/yRad)*(yDiff/yRad) <= 1 ){
// If the pixel is contained in the ellipse, set it to true
canvas->setPixel(x, y, true);
}
}
}
}
///////////////////////// End Ellipse /////////////////////////
////////////////////////// Circle //////////////////////////
// PUT YOUR CODE (IMPLEMENTATIONS) FOR CIRCLE HERE
Circle::Circle(double rad_in)
: Ellipse(rad_in, rad_in) {}
//Use Ellipse's area function by sending it the radius of the
//circle for the xRad and yRad parameters
//Use Ellipse's draw function
///////////////////////// End Circle /////////////////////////
//////////////////////// Rectangle /////////////////////////
// PUT YOUR CODE (IMPLEMENTATIONS) FOR RECTANGLE HERE
Rectangle::Rectangle(double w_in, double h_in)
: w(w_in), h(h_in) {}
double Rectangle::area() const {
return w * h;
}
void Rectangle::draw(Canvas *canvas) const{
// Iterate through the grid of (x,y) pixel coordinates
// in the canvas.
for(int x = 0; x < CANVAS_WIDTH; ++x){
for(int y = 0; y < CANVAS_HEIGHT; ++y){
// The Rectangle contains the point (x,y) if and only if
// ((x-xPos)/xRad)^2 + ((y-yPos)/yRad)^2 <= 1
double xDiff = x - get_xPos();
double yDiff = y - get_yPos();
if( abs(xDiff) <= w/2 && abs(yDiff) <= h/2 ){
// If the pixel is contained in the Rectangle, set it to true
canvas->setPixel(x, y, true);
}
}
}
}
//////////////////////// End Rectangle //////////////////////
Along with the corresponding .h file:
// Shapes.h
#ifndef SHAPES_H
#define SHAPES_H
#include "Canvas.h"
/////////////////////////// Shape ///////////////////////////
class Shape {
public:
//EFFECTS: creates a shape with initial position (0,0)
Shape() : xPos(0), yPos(0) {}
//EFFECTS: returns the area of this Shape
virtual double area() const = 0;
//MODIFIES: canvas
//EFFECTS: draws this shape onto canvas at its current position
virtual void draw(Canvas *canvas) const {}
//MODIFIES: xPos, yPos
//EFFECTS: sets the position of this shape
void setPosition(double xPos_in, double yPos_in){
xPos = xPos_in;
yPos = yPos_in;
}
double get_xPos() const { return xPos; }
double get_yPos() const { return yPos; }
private:
double xPos; // The x position of this shape
double yPos; // The y position of this shape
};
///////////////////////// End Shape /////////////////////////
////////////////////////// Ellipse //////////////////////////
class Ellipse : public Shape{
public:
Ellipse();
//REQUIRES: xRad_in, yRad_in are non-negative
//EFFECTS: creates an Ellipse with given x and y radii
Ellipse(double xRad_in, double yRad_in);
//EFFECTS: returns the area of this Ellipse
virtual double area() const;
//MODIFIES: canvas
//EFFECTS: draws this shape onto canvas
virtual void draw(Canvas *canvas) const;
private:
double xRad; //Half the x-axis of the ellipse
double yRad; //Half the y-axis of the ellipse
};
///////////////////////// End Ellipse ////////////////////////
///////////////////////////////////////////////////////////////
// DO NOT MODIFY ABOVE THIS LINE //
///////////////////////////////////////////////////////////////
////////////////////////// Circle //////////////////////////
// PUT YOUR CODE (DECLARATION) FOR CIRCLE HERE
class Circle : public Ellipse{
public:
//REQUIRES: rad_in is non-negative
//EFFECTS: creates an Circle with given radius
Circle(double rad_in);
//EFFECTS: returns the area of this Circle
virtual double area() const;
//MODIFIES: canvas
//EFFECTS: draws this shape onto canvas
virtual void draw(Canvas *canvas) const;
private:
double xRad; //Radius of the Circle
double yRad; //Radius of the Circle
};
///////////////////////// End Circle /////////////////////////
//////////////////////// Rectangle /////////////////////////
// PUT YOUR CODE (DECLARATION) FOR RECTANGLE HERE
class Rectangle : public Shape{
public:
//REQUIRES: xRad_in, yRad_in are non-negative
//EFFECTS: creates an Rectangle with given x and y radii
Rectangle(double w_in, double h_in);
//EFFECTS: returns the area of this Rectangle
virtual double area() const;
//MODIFIES: canvas
//EFFECTS: draws this shape onto canvas
virtual void draw(Canvas *canvas) const;
private:
double w; //Length of the Rectangle
double h; //Width of the Rectangle
};
//////////////////////// End Rectangle //////////////////////
#endif /* SHAPES_H */
I am supposed to be making Rectangle derived from Shape and Circle derived from Ellipse, both with the corresponding functions that are present in their implementations, and I thought my code had done so, but I got the following compiler error:
shapes.cpp: In constructor \u2018Circle::Circle(double)\u2019:
shapes.cpp:47:30: error: no matching function for call to \u2018Ellipse::Ellipse()\u2019
: xRad(rad_in), yRad(rad_in) {}
^
shapes.cpp:47:30: note: candidates are:
shapes.cpp:12:1: note: Ellipse::Ellipse(double, double)
Ellipse::Ellipse(double xRad_in, double yRad_in)
^
shapes.cpp:12:1: note: candidate expects 2 arguments, 0 provided
In file included from shapes.cpp:4:0:
shapes.h:45:7: note: Ellipse::Ellipse(const Ellipse&)
class Ellipse : public Shape{
^
shapes.h:45:7: note: candidate expects 1 argument, 0 provided
I really have no idea what's wrong. Please help!
EDIT: Additional Code necessary for compile:
// Canvas.cpp
#include <iostream>
#include <cassert>
#include "Canvas.h"
using namespace std;
///////////////////////// Canvas ///////////////////////////
Canvas::Canvas(){
for(int row = 0; row < CANVAS_HEIGHT; ++row){
for(int col = 0; col < CANVAS_WIDTH; ++col){
grid[row][col] = false;
}
}
}
void Canvas::setPixel(int x, int y, bool value){
assert(0 <= x); assert(x < CANVAS_WIDTH);
assert(0 <= y); assert(y < CANVAS_HEIGHT);
grid[y][x] = value;
}
void Canvas::print() const {
for(int row = 0; row < CANVAS_HEIGHT; ++row){
for(int col = 0; col < CANVAS_WIDTH; ++col){
cout << (grid[CANVAS_HEIGHT-row-1][col] ? PIXEL_ON : PIXEL_OFF) << " ";
}
cout << endl;
}
}
////////////////////////// End Canvas /////////////////////////
And Canvas.h:
#ifndef CANVAS_H
#define CANVAS_H
///////////////////////// Canvas ///////////////////////////
//Canvas Constants
const int CANVAS_WIDTH = 30;
const int CANVAS_HEIGHT = 30;
const char PIXEL_ON = '#';
const char PIXEL_OFF = ' ';
class Canvas {
//OVERVIEW: A Canvas object represents a 2D grid of "pixels"
// which can be set to either "on" or "off". A Canvas
// knows how to print itself out to the terminal. The
// canvas has a fixed width and height and the origin
// (0,0) of the canvas's coordinate system is at the
// bottom left.
public:
//EFFECTS: creates a new Canvas with size CANVAS_WIDTH x CANVAS_HEIGHT
Canvas();
//REQUIRES: the pixel is on the canvas (0 <= x < CANVAS_WIDTH, 0 <= y < CANVAS_HEIGHT)
//MODIFIES: grid
//EFFECTS: if value is true, turns the pixel at (x,y) on
// if value is false, turns the pixel at (x,y) off
void setPixel(int x, int y, bool value);
//EFFECTS: prints this canvas to cout
void print() const;
private:
bool grid[CANVAS_HEIGHT][CANVAS_WIDTH];
};
////////////////////////// End Canvas /////////////////////////
#endif /* CANVAS_H */
Circle inherits from Ellipse, but Ellipse does not have a default constructor. Therefore either provide one, or call the desired constructor of Ellipse in the initialization list of Circle's constructor.
Related
I'm currently learning C++ by creating an N body simulation. In order to improve the number of bodies in my simulations I'm trying to implement the Barnes Hut approximation method. I'm actually coding a QuadTree structure in C++ (see below).
In order to construct my tree, I define three classes :
class Point : Corresponding to the bodies of my simulation with x and y position as attributes
class Rectangle : Corresponding to the properties of the leaves of my tree with position and dimension attributes
class QuadTree : Corresponding to my QuadTree and its children (leaves) and a Rectangle object, a vector of Point objects, four leaves objects (QuadTree) and a boolean to say if it contain leaves or not.
I wrote a main function where I define my tree with its boudaries and I divide it to make appear four leaves. Then I ask informations about my tree and the associated subtrees using the function void QuadTree::get_information(). This function allows to show some information about the current tree by displaying if it has children or not (divided), its boudaries, and the points it contains. If it has children, then we apply the function QuadTree::get_information() on each child and we repeat the process.
The problem is that the code give an error of this kind :
QuadTree : Capacity = 1, Divided (0:False, 1:True) = 0
Rectangle : Center Position = (0, 0), Width = 10, Height = 10
-------------------
-------------------
QuadTree : Capacity = 1, Divided (0:False, 1:True) = 1
Rectangle : Center Position = (0, 0), Width = 10, Height = 10
Northwest :
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted (core dumped)
It seems that I have a problem of allocation memory. I think I make a bad use of the pointers NW, NE, SW, SE defined in the QuadTree class.
I'm not an expert of the utilisation of the memory allocation on C++, maybe I do a naive error. Do you see something wrong about the way a manage these pointers ? Could you suggest a solution to my problem and make run my algorithm ?
Thank you so much for your time ! :)
#include <iostream> //For console output/input
#include <fstream> //Allows to read/write files
#include <math.h> //Basic mathematic functions
#include <vector> //For dynamic arrays
#include <string> //Operations on strings
#include <tuple>
#include <cmath>
#include <sstream>
using namespace std;
class Point
{
public :
double get_x();
double get_y();
void set_x(double xp);
void set_y(double yp);
void get_information();
private :
double x;
double y;
};
double Point::get_x(){return x;}
double Point::get_y(){return y;}
void Point::set_x(double xp){x = xp;}
void Point::set_y(double yp){y = yp;}
class Rectangle
{
public :
double get_x();
double get_y();
double get_w();
double get_h();
void set_x(double xc);
void set_y(double yc);
void set_w(double wc);
void set_h(double hc);
bool contain(Point pt);
void get_information();
private :
double x;
double y;
double w;
double h;
};
double Rectangle::get_x() {return x;}
double Rectangle::get_y() {return y;}
double Rectangle::get_w() {return w;}
double Rectangle::get_h() {return h;}
void Rectangle::set_x(double xc) {x = xc;}
void Rectangle::set_y(double yc) {y = yc;}
void Rectangle::set_w(double wc) {w = wc;}
void Rectangle::set_h(double hc) {h = hc;}
class QuadTree
{
public :
Rectangle get_boundary();
int get_capacity();
void set_boundary(double xc, double yc, double wc, double hc);
void set_rectangle(Rectangle rect);
void set_capacity(int capacity);
void insert(Point pt);
void subdivide();
void set_divided();
bool is_divided();
void get_information();
QuadTree getNW();
QuadTree getNE();
QuadTree getSW();
QuadTree getSE();
void setNW(QuadTree nw);
void setNE(QuadTree ne);
void setSW(QuadTree sw);
void setSE(QuadTree se);
private :
QuadTree* NW=NULL;
QuadTree* NE=NULL;
QuadTree* SW=NULL;
QuadTree* SE=NULL;
Rectangle boundary;
vector<Point> p;
bool divided = false;
};
QuadTree QuadTree::getNW(){return *NW;}
QuadTree QuadTree::getNE(){return *NE;}
QuadTree QuadTree::getSW(){return *SW;}
QuadTree QuadTree::getSE(){return *SE;}
void QuadTree::setNW(QuadTree nw){NW=&nw;}
void QuadTree::setNE(QuadTree ne){NE=≠}
void QuadTree::setSW(QuadTree sw){SW=&sw;}
void QuadTree::setSE(QuadTree se){SE=&se;}
bool QuadTree::is_divided(){return divided;}
bool Rectangle::contain(Point pt)
{
return (pt.get_x() > get_x() - get_w()
and pt.get_x() < get_x() + get_w()
and pt.get_y() > get_y() - get_h()
and pt.get_y() < get_y() + get_h());
}
Rectangle QuadTree::get_boundary() {return boundary;}
void QuadTree::set_boundary(double xc, double yc, double wc, double hc)
{
boundary.set_x(xc);
boundary.set_y(yc);
boundary.set_w(wc);
boundary.set_h(hc);
}
//int QuadTree::get_capacity() {return n;}
//void QuadTree::set_capacity(int capacity) {n = capacity;}
void QuadTree::set_divided() {divided = true;}
void QuadTree::set_rectangle(Rectangle rect) {boundary = rect;}
void QuadTree::subdivide()
{
double xc = boundary.get_x();
double yc = boundary.get_y();
double wc = boundary.get_w();
double hc = boundary.get_h();
Rectangle nw;
nw.set_x(xc-wc/2.);
nw.set_y(yc+hc/2.);
nw.set_w(wc/2.);
nw.set_h(hc/2.);
Rectangle ne;
ne.set_x(xc+wc/2.);
ne.set_y(yc+hc/2.);
ne.set_w(wc/2.);
ne.set_h(hc/2.);
Rectangle sw;
sw.set_x(xc-wc/2.);
sw.set_y(yc-hc/2.);
sw.set_w(wc/2.);
sw.set_h(hc/2.);
Rectangle se;
se.set_x(xc-wc/2.);
se.set_y(yc+hc/2.);
se.set_w(wc/2.);
se.set_h(hc/2.);
QuadTree oNW, oNE, oSW, oSE;
oNW.set_rectangle(nw);
oNE.set_rectangle(ne);
oSW.set_rectangle(sw);
oSE.set_rectangle(se);
setNW(oNW);
setNE(oNE);
setSW(oSW);
setSE(oSE);
//NW = &oNW;
//NE = &oNE;
//SW = &oSW;
//SE = &oSE;
}
void QuadTree::insert(Point pt)
{
if (! get_boundary().contain(pt) ) {cout<<"Hello 1"<<endl; return; }
if (p.size() < 1)
{
cout<<"Hello 2"<<endl;
p.push_back(pt); // Insert element at the end
}
else
{
if (!divided)
{
QuadTree::subdivide();
QuadTree::set_divided();
}
}
NW->insert(pt);
NE->insert(pt);
SW->insert(pt);
SE->insert(pt);
}
void Point::get_information(){cout<<"Point : x = "<<get_x()<<"; y = "<<get_y()<<endl;}
void Rectangle::get_information(){cout<<"Rectangle : Center Position = ("<<get_x()<<", "<<get_y()<<"), Width = "<<get_w()<<", Height = "<<get_h()<<endl;}
void QuadTree::get_information()
{
cout<<"QuadTree : Capacity = "<<" 1"<<", Divided (0:False, 1:True) = "<<divided<<endl;
boundary.get_information();
/*cout<<"Points_in : "<<endl;
int siz = p.size();
for (int ii=0; ii<siz; ii++)
{
p[ii].get_information();
}*/
if (divided) {
cout<<" Northwest : "<<endl;
getNW().get_information();
cout<<" Northeast : "<<endl;
getNE().get_information();
cout<<" Southwest : "<<endl;
getSW().get_information();
cout<<" Southeast : "<<endl;
getSE().get_information();
}
}
int main()
{
QuadTree tree;
tree.set_boundary(0., 0., 10., 10.);
tree.get_information();
cout<<"-------------------"<<endl;
tree.subdivide();
tree.set_divided();
cout<<"-------------------"<<endl;
tree.get_information();
}
I've been writing a program for CS class that's supposed to get the X and Y coordinates from the user, as well as the length of a square and the height of the cube, and it should then calculate the area of the square and the surface area and volume of the cube (plus some coordinates stuff but that's not a pressing issue right now)
I've written the test file and it compiled successfully, but I've been getting very long answers for the square and cube properties that are obviously wrong. Can anyone point out whatever logical errors I might have or if I have the access specification and relationship between the classes wrong?
Point.h
class Point
{
protected:
double Xint, Yint;
public:
Point();
void setX(double);
void setY(double);
double getX() const;
double getY() const;
};
Point.ccp
Point::Point()
{
Xint = 0;
Yint = 0;
}
void Point::setX(double x)
{ Xint = x; }
void Point::setY(double y)
{ Yint = y; }
double Point::getX() const
{ return Xint; }
double Point::getY() const
{ return Yint; }
Square.h
#include "Point.h"
class Square : public Point
{
protected:
Point lowerLeft;
double sideLength;
public:
Square(double sideLength, double x, double y) : Point()
{
sideLength = 0.0;
x = 0.0;
y = 0.0;
}
void setLowerLeft(double, double);
void setSideLength(double);
double getSideLength() const;
double getSquareArea() const;
};
Square.ccp
#include "Square.h"
void Square::setLowerLeft(double x, double y)
{
lowerLeft.setX(x);
lowerLeft.setY(y);
}
void Square::setSideLength(double SL)
{ sideLength = SL; }
double Square::getSideLength() const
{ return sideLength; }
// Calculate the area of square
double Square::getSquareArea() const
{ return sideLength * sideLength; }
Cube.h
#include "Square.h"
class Cube : public Square
{
protected:
double height;
double volume;
public:
Cube(double height, double volume) : Square(sideLength, Xint, Yint)
{
height = 0.0;
volume = 0.0;
}
double getSurfaceArea() const;
double getVolume() const;
};
Cube.ccp
#include "Cube.h"
// Redefine GetSquareArea to calculate the cube's surface area
double Cube::getSurfaceArea() const
{ return Square::getSquareArea() * 6; }
// Calculate the volume
double Cube::getVolume() const
{ return getSquareArea() * height; }
"Can anyone point out whatever logical errors I might have or if I have the access specification and relationship between the classes wrong?"
Well, from our well known 3-dimensional geometry a cube is made up from exactly 6 squares.
So how do you think inheriting a Cube class from a Square actually should work well?
You can easily define a Cube class by means of a fixed Point (e.g. the upper, left, front corner) and a fixed size of the edge length.
If you really want and need to, you can add a convenience function for your Cube class, that returns all of the 6 Squares it consist of in 3 dimensional space:
class Cube {
public:
Cube(const Point& upperLeftFrontCorner, double edgeLength);
std::array<Square,6> getSides() const;
};
Well friends, I have returned here to try and get a little help once again. The issue is this, the ship on build doesn't wrap. That is to say it doesn't reappear on the other side of the window when it goes past the windows limit. The function called setmaxLocations() is being very strange. It erases the ship, or doesn't set the max location. So here is my code. Bear with me, this is a large project. If I messed up the format just let me know, I check often so it'll get fixed close to when you tell me.
main implementation cpp:
#include <SFML/Graphics.hpp>
#include "ship.h"
const int WINDOW_WIDTH = 700;
const int WINDOW_HEIGHT = 700;
//==============================================================================
int main()
{
Ship ship;
sf::RenderWindow window( sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT),
"Delta Quadrant", sf::Style::Titlebar | sf::Style::Close);
window.setFramerateLimit(120);
// this causes loop to execute 120 times a second at most.
// (a delay is automatically added after screen is drawn)
//set's the limit on the ship's location to the window dimensions;
ship.setmaxLocations(WINDOW_WIDTH, WINDOW_HEIGHT);
//sets position of the ship in the middle of the screen
ship.setLocation(WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
while (window.isOpen())
{
//----------------------------------------------------------
//handle user input (events and keyboard keys being pressed)
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}
//turn left with press of left button
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
ship.rotateLeft();
//turn right with press of right button
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
ship.rotateRight();
//apply thrust with press of up button
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
ship.applyThrust();
//----------------------------------------------------------
//draw new frame
window.clear();
//draw ship
ship.updateLocation();
ship.draw(window);
//redisplay window
window.display();
}
return 0;
}
SpaceObject header:
#ifndef SPACE_OBJECT_H
#define SPACE_OBJECT_H
#include "vector.h"
class SpaceObject {
private:
Vector maxLocations; //maximum allowable values for location
Vector location; //current location (x,y)
Vector velocity; //current velocity (in pixels/frame)
double angleDeg; //angle ship is facing, in degrees
double radius; //gross radius (for collision detection)
public:
SpaceObject();
//--------------------------------------------
//mutators
void setLocation(double x, double y);
void setVelocity(double velocityX, double velocityY);
void setAngle(double angDeg);
void setRadius(double radius);
//--------------------------------------------
//accessors
Vector getLocation();
Vector getVelocity();
double getAngle();
double getRadius();
//--------------------------------------------
//others
void updateLocation();
void setmaxLocations(double x, double y);
};
#endif
SpaceObject source file:
#include<cmath>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include"vector.h"
#include "SpaceObject.h"
//constructor
SpaceObject::SpaceObject() {
maxLocations.x = 500;
maxLocations.y = 500;
radius = 5;
location.x = 0;
location.y = 0;
velocity.x = 0;
velocity.y = 0;
angleDeg = 0;
}
//================================================================
//mutators
//================================================================
// Function: setLocation
//
// Description: Sets the x and y values of the SpaceObject's location
// Argument list:
// x(I) - x coordinate for SpaceObject's location
// y(I) - y coordinate for SpaceObject's location
//=================================================================*/
void SpaceObject::setLocation(double x, double y){
//Check and correct for the SpaceObject going out of bounds.
if (x < 0)
location.x += maxLocations.x;
else if (x > maxLocations.x)
location.x -= maxLocations.x;
else
location.x = x;
if (y < 0)
location.y += maxLocations.y;
else if (y > maxLocations.y)
location.y -= maxLocations.y;
else
location.y = y;
}
//================================================================
// Function: setVelocity
//
// Description: Sets the velocity for the x and y direction of the SpaceObject
// Argument list:
// velocityX(I) - sets the velocity in the x direction
// velocityY(I) - sets the velocity in the y direction
//=================================================================
void SpaceObject::setVelocity(double velocityX, double velocityY){
velocity.x = velocityX;
velocity.y = velocityY;
}
//================================================================
// Function: setLocation
//
// Description: Sets the directional angle of the SpaceObject
// Argument List:
// angDeg(I) - sets the SpaceObjects angle
//=================================================================*/
void SpaceObject::setAngle(double angDeg){
while (angDeg >= 360)
angDeg -= 360;
while (angDeg < 0)
angDeg += 360;
angleDeg = angDeg;
}
//================================================================
//accessors
//================================================================
// Function: getRadius
// Description: Returns the Radius
//
// Return value:
// Radius - the SpaceObjects turning axis
//=================================================================*/
double SpaceObject::getRadius(){
return radius;
}
//================================================================
// Function: getLocation
// Description: Returns the x and y values of the SpaceObjects location
//
// Return value:
// location - the location of the SpaceObject
//=================================================================*/
Vector SpaceObject::getLocation(){
return location;
}
//================================================================
// Function: getVelocity
// Description: Returns the x and y values of the SpaceObjects directional velocity
//
// Return value:
// Velocity
//=================================================================*/
Vector SpaceObject::getVelocity(){
return velocity;
}
//================================================================
// Function: getAngle
// Description: returns the angle
//
// Return value:
// Angle - the SpaceObjects direction
//=================================================================*/
double SpaceObject::getAngle(){
return angleDeg;
}
//============================================
//other functions
//================================================================
// Function: setmaxLocations
//
// Description: Sets the x and y values of the SpaceObject's max possible area of movement
// Argument list:
// x(I) - max width of SpaceObject's possible positions
// y(I) - max heigth of SpaceObject's possible positions
//=================================================================*/
void SpaceObject::setmaxLocations(double x, double y){
maxLocations.x = x;
maxLocations.y = y;
}
//================================================================
// Function: updateLocations
//
// Description: Sets the x and y values of the SpaceObject's location while including the change with velocity
//=================================================================*/
void SpaceObject::updateLocation(){
location.x = location.x + velocity.x;
location.y = location.y + velocity.y;
}
ship header file:
#ifndef SHIP_H
#define SHIP_H
#include "SpaceObject.h"
class Ship: public SpaceObject {
public:
Ship();
void rotateLeft();
void rotateRight();
void applyThrust();
void draw(sf::RenderWindow& win);
};
#endif
ship source file:
#include<cmath>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include"vector.h"
#include "ship.h"
//Constants
const double PI = 3.14159;
const double THRUST = 0.005;
const double TURN_SPEED = 1;
Ship::Ship() {
}
//============================================
//other functions
//================================================================
// Function: rotateLeft
//
// Description: turns the ship left by subtracting from the ship's angle
//=================================================================*/
void Ship::rotateLeft(){
int newAngle;
newAngle = getAngle() - TURN_SPEED;
setAngle(newAngle);
}
//================================================================
// Function: rotateRight
//
// Description: turns the ship Right by adding to the ship's angle
//=================================================================*/
void Ship::rotateRight(){
int newAngle;
newAngle = getAngle() + TURN_SPEED;
setAngle(newAngle);
}
//================================================================
// Function: applyThrust
//
// Description: Sets the x and y value of the ship's movement
//=================================================================*/
void Ship::applyThrust(){
double forcex = cos((getAngle()-90)*PI/180) * .005;
double forcey = sin((getAngle()-90)*PI/180) * .005;
setVelocity(getVelocity().x + forcex, getVelocity().y + forcey);
}
//--------------------------------------------------------------------------
// Function: draw
// Description: draws the ship on the given window
// Parameters:
// win - the window for drawing the ship
//--------------------------------------------------------------------------
void Ship::draw(sf::RenderWindow& win) {
// draw ship
sf::ConvexShape ship;
ship.setPointCount(3);
ship.setPoint(0, sf::Vector2f(10, 0));
ship.setPoint(1, sf::Vector2f(0, 25));
ship.setPoint(2, sf::Vector2f(20, 25));
sf::Vector2f midpoint(10,15);
ship.setOrigin(midpoint);
ship.setFillColor(sf::Color(0, 0, 0));
ship.setOutlineThickness(1);
ship.setOutlineColor(sf::Color(255, 255, 255));
ship.setPosition(getLocation().x, getLocation().y);
ship.setRotation(getAngle());
win.draw(ship);
}
vector header file (just for clarity):
#ifndef VECTOR_H
#define VECTOR_H
struct Vector{
float x;
float y;
};
#endif
It seems that SpaceObject::setLocation() does the actual checking to see if the ship is in bounds, yet this function is only called once at the beginning of your main(). It needs to be called within the loop so it can continually check that the ship has a valid location. I would recommend calling it within SpaceObject::updateLocation()
Both base classes, Arc and Lines, are derived from class Shape.
The compiler says Ojbect b1 "error: shape is ambiguous". I know that two instances of Shape are being created, but don't know how to resolve it?
Graph_lib::Box b1(Point,100,100), 100,100);
win1.attach(b1);
This class will be able to draw a box with rounded corners. I just wrote the code for the Box Lines part, I didn't get to the Arc yet since this won't even work.
//------------------------------------------------------------------------------
struct Box : Lines , Arc {
Box(Point xy, int ww, int hh);
void Top_segment();
void Bottom_segment();
void Left_side_segment();
void Right_side_segment();
void draw_lines() const;
int height() const { return h; }
int width() const { return w; }
private:
int h; // height
int w; // width
double width_tenth; //10% of the width that will calculate the length to remove from each side to make room for the arcs
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Box::Box(Point xy, int ww, int hh): w(ww), h(hh)
{
width_tenth = (xy.x + w) * 0.10;
if (h<=0 || w<=0) error("Bad box: non-positive side");
}
//------------------------------------------------------------------------------
void Box::Top_segment()
{
double top_seg_begin_w; //where the line segment will begin after deducting 10% of w;
double top_seg_end_w; //where the line segment will end after deducting 10% of w;
top_seg_begin_w = xy.x + width_tenth;
top_seg_end_w = (xy.x + w) - width_tenth;
Lines::add(Point(top_seg_begin_w,xy.y),Point(top_seg_end_w,xy.y));
}
//------------------------------------------------------------------------------
void Box::Bottom_segment()
{
double bottom_seg_begin_w;
double bottom_seg_end_w;
bottom_seg_begin_w = xy.x + width_tenth;
bottom_seg_end_w = (xy.x + w) - width_tenth;
double y_bottom = xy.y + h;
Lines::add(Point(bottom_seg_begin_w,y_bottom),Point(bottom_seg_end_w,y_bottom));
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Box::Left_side_segment()
{
double left_seg_begin_h;
double left_seg_end_h;
left_seg_begin_h = xy.y + width_tenth;
left_seg_end_h = (xy.y + h) - width_tenth;
double x_left = xy.x;
Lines::add(Point(x_left,left_seg_begin_h),Point(x_left,left_seg_end_h));
}
//------------------------------------------------------------------------------
void Box::Right_side_segment()
{
double right_seg_begin_h;
double right_seg_end_h;
right_seg_begin_h = xy.y + width_tenth;
right_seg_end_h = (xy.y + h) - width_tenth;
double x_right = xy.x + w;
Lines::add(Point(x_right,right_seg_begin_h),Point(x_right,right_seg_end_h));
}
//------------------------------------------------------------------------------
Use virtual inheritance for classes Lines and Arc. For example
class Lines : virtual public Shape
{
//...
};
class Arc : virtual public Shape
{
//...
};
Ok, I'm having this problem with my Sprite class. Basically the sprite class should have a object of class Vector as its member with Vector being a class with both angle and speed. The Vector class has a Vector(double,double) constructor so the speed and angle can be set at its initialization but when I make my sprite class. It sends an error that its calling Vector(), a blank constructor, and that it doesn't exist. I'm trying to figure out why its calling Vector(). Here is my code from both the Sprite and Vector classes.
#Vector.h
#ifndef VECTOR_H
#define VECTOR_H
class Vector
{
public:
Vector(double,double);
double getX();
double getY();
double getSpeed();
double getAngle();
void setSpeed(double);
void setAngle(double);
private:
double speed,angle;
};
#endif
#Vector.h
#include "SDL/SDL.h"
#include "vector.h"
#include "math.h"
Vector::Vector(double speed,double angle)
{
this -> speed = speed;
this -> angle = angle;
}
double Vector::getX()
{
return speed*cos(angle);
}
double Vector::getY()
{
return speed*sin(angle);
}
double Vector::getSpeed()
{
return speed;
}
double Vector::getAngle()
{
return angle;
}
void Vector::setAngle(double angle)
{
this -> angle = angle;
}
void Vector::setSpeed(double speed)
{
this -> speed = speed;
}
#Sprite.h:
#ifndef SPRITE_H
#define SPRITE_H
#include "vector.h"
class Sprite
{
public:
Sprite(int x,int y);
SDL_Rect getRect();
SDL_Surface* getImage();
void setRect(SDL_Rect);
void move();
void draw(SDL_Surface*);
private:
Vector movement;
double x,y,lastX,lastY,angle,speed;
SDL_Rect rect;
SDL_Surface* image;
};
#endif
#Sprite.cpp:
#include "SDL/SDL.h"
#include "sprite.h"
#include "functions.h"
#include <cmath>
Sprite::Sprite(int x, int y)
{
this -> x = x;
this -> y = y;
lastX = x;
lastY = y;
image = loadImage("box.png");
rect.x = x;
rect.y = y;
rect.w = image->w;
rect.h = image->h;
speed = 1;
angle = 0;
}
SDL_Rect Sprite::getRect()
{
return rect;
}
SDL_Surface* Sprite::getImage()
{
return image;
}
void Sprite::setRect(SDL_Rect rect)
{
this -> rect = rect;
}
void Sprite::move()
{
lastX = x;
lastY = y;
x += speed*cos(angle);
y += speed*sin(angle);
rect.x = int(x);
rect.y = int(y);
}
void Sprite::draw(SDL_Surface* dest)
{
blit(image,dest,int(x),int(y));
}
Your Sprite class has a Vector member that will be constructed when the Sprite is constructed. At the moment, the Vector will be initialized with the default constructor because you haven't specified otherwise. If you want a specific constructor of Vector to be used, you need to add an initialization list to the constructor of Sprite:
Sprite::Sprite(int x, int y)
: movement(1.0, 0.0)
{
// ...
}
This will initialise movement with arguments 1 and 0. In fact, you might as well add other members to your initialization list too:
Sprite::Sprite(int x, int y)
: movement(1.0, 0.0), x(x), y(y), lastX(x), lastY(y) // and so on...
{
// ...
}
The Vector is created in Sprite::Sprite(int x, int y). The blank constructor for Vector is called because you do not call a constructor in the initializer list: in fact, you leave the Vector movement completely uninitialized!
Do this:
Sprite::Sprite(int x, int y):
movement(3.14, 2.7)
{
...
}
to construct movement using a two argument constructor. I would pick better values than 3.14 and 2.7, those are just sample values.
I would also consider creating a public no-argument constructor on Vector for ease of use that initalizes speed and angle to zero.