C++ functions of pointers to classes don't work? - c++

I'm trying to generate a terrain using perlin noise, to improve the quality of the terrain, I want to use multiple noises at once. So I have written a class that should to that for me. Here are the hpp and cpp files:
#include "perlinNoise.hpp"
class MultiPerlinNoise: public PerlinNoise {
public:
MultiPerlinNoise();
std::vector<PerlinNoise*> perlinNoises;
float octaveNoise(float x, float y);
};
cpp:
#include "multiPerlinNoise.hpp"
MultiPerlinNoise::MultiPerlinNoise():
PerlinNoise(0) {
}
float MultiPerlinNoise::octaveNoise(float x, float y) {
float sum = 0.0f;
for(int i = 0; i < perlinNoises.size(); i++)
sum += perlinNoises[i]->octaveNoise(x, y);
return sum;
}
The PerlinNoise class is a wrapper around the code for a octave peril noise I found on the internet. It looks like this:
#include "sivPerlinNoise.hpp"
class PerlinNoise {
public:
PerlinNoise(unsigned int seed);
float octaveNoise(float x, float y);
float frequency;
float multiplier;
int octaves;
unsigned int seed;
float offset;
private:
siv::PerlinNoise perlinNoise;
};
cpp:
#include "perlinNoise.hpp"
PerlinNoise::PerlinNoise(unsigned int seed):
perlinNoise(seed), frequency(2.0f), multiplier(1.0f), octaves(1), seed(seed), offset(0.0f) {
}
float PerlinNoise::octaveNoise(float x, float y) {
return perlinNoise.octaveNoise(x / frequency, y / frequency, octaves) * multiplier + offset;
}
Now the problem is, that when I pass a pointer to my noise into my map class, the function always return 0.0f. This is how the constructor of my map class looks like:
Map::Map(PerlinNoise *noise, Shader *shader, const RenderData *data):
noise(noise), shader(shader), data(data), texture("resources/textures/stones.png") {
printf("%f\n", noise->octaveNoise(-(CHUNK_SIZE / 2.0f) + 0.0f, -(CHUNK_SIZE / 2.0f) + 0.0f));
update(glm::vec3(0.0f));
}
When I don't use a pointer to my noise everything is working as it should. How can this be fixed?

You need to declare octaveNoise as virtual, so the method can be overridden by inheriting classes:
class MultiPerlinNoise: public PerlinNoise {
public:
MultiPerlinNoise();
std::vector<PerlinNoise*> perlinNoises;
virtual float octaveNoise(float x, float y);
};

Related

Defining header files in C++

To start off with, I'll mention I come mainly from a Java background. I do have exposure with C and understand most concepts behind C++. I'm trying to help myself learn more about the language and can't seem to figure out headers. I understand why to use them in addition to cpp files and all of that. My problem is trying to actually manage working with them. For example, defining a Vector3 header with private float variables and then overload operating. My problem comes in when I attempt to define the constructor and methods in the cpp file. I can't seem to figure out how to get access to the private variables without specifically defining the functions and the constructor in the header, which more or less leads me to believe I don't need both a header and cpp file in this instance.
Here's how I've defined the header file currently (which works, but isn't undefined as it should be):
#pragma once
#ifndef __Vector_3_H__
#define __Vector_3_H__
namespace VectorMath {
class Vector3 {
public:
Vector3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
Vector3 operator+(Vector3 vector) {
return Vector3(x + vector.x, y + vector.y, z + vector.z);
}
Vector3 operator-(Vector3 vector) {
return Vector3(x - vector.x, y - vector.y, z - vector.z);
}
Vector3 operator*(Vector3 vector) {
return Vector3(x * vector.x, y * vector.y, z * vector.z);
}
Vector3 operator/(Vector3 vector) {
return Vector3(x / vector.x, y / vector.y, z / vector.z);
}
float getX() {
return x;
}
float getY() {
return y;
}
float getZ() {
return z;
}
private:
float x;
float y;
float z;
};
}
#endif
It needs to look more like this instead:
Vector_3.h:
#ifndef Vector_3_H
#define Vector_3_H
#pragma once
namespace VectorMath {
class Vector3 {
public:
Vector3(float x, float y, float z);
Vector3 operator+(Vector3 vector);
Vector3 operator-(Vector3 vector);
Vector3 operator*(Vector3 vector);
Vector3 operator/(Vector3 vector);
float getX();
float getY();
float getZ();
private:
float x;
float y;
float z;
};
}
#endif
Vector_3.cpp:
#include "Vector_3.h"
namespace VectorMath {
Vector3::Vector3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
Vector3 Vector3::operator+(Vector3 vector) {
return Vector3(x + vector.x, y + vector.y, z + vector.z);
}
Vector3 Vector3::operator-(Vector3 vector) {
return Vector3(x - vector.x, y - vector.y, z - vector.z);
}
Vector3 Vector3::operator*(Vector3 vector) {
return Vector3(x * vector.x, y * vector.y, z * vector.z);
}
Vector3 Vector3::operator/(Vector3 vector) {
return Vector3(x / vector.x, y / vector.y, z / vector.z);
}
float Vector3::getX() {
return x;
}
float Vector3::getY() {
return y;
}
float Vector3::getZ() {
return z;
}
}
If you want to use a cpp file for your constructor you should write
// File Vector3.cpp
#include "Vector3.h"
namespace VectorMath {
Vector3::Vector3 (float x, float y, float z)
{
this->x=x;
//...
}
The addition should be implemented as follows if you keep it in the same namespace
Vector3 Vector3::operator+(const Vector3& v)
{
return Vector3 (x+v.x,y+v.y,z+v.z);
}
}
If you want to move the implementations of member functions away from the header file, you still need to declare them in the definition of the class. For example:
// Vector1.h
#pragma once
#ifndef VectorMath_Vector1_H
#define VectorMath_Vector1_H
namespace VectorMath {
class Vector1 {
public: // Methods:
// This is a definition for a default constructor:
Vector1() noexcept : m_x(0) {}
// This is a declaration for another constructor:
Vector1(float x) noexcept;
// This is a declaration of a member function:
Vector1 operator+(Vector1 const & rhs) const noexcept;
private: // Fields:
float m_x;
}; // class Vector1
} // namespace VectorMath {
#endif // VectorMath_Vector1_H
// Vector1.cpp
#include "Vector1.h"
namespace VectorMath {
// Definition of the other constructor:
Vector1::Vector1(float x) noexcept
: m_x(x)
{}
// Definition of the binary + operator:
Vector1 Vector1::operator+(Vector1 const & rhs) const noexcept
{ return m_x + rhs.m_x; }
} // namespace VectorMath {

Point, square, and cube program help on C++

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

C++ inheritance (overriding constructors)

I am learning OpenGL w/ C++. I am building the asteroids game as an exercise. I'm not quite sure how to override the constructors:
projectile.h
class projectile
{
protected:
float x;
float y;
public:
projectile();
projectile(float, float);
float get_x() const;
float get_y() const;
void move();
};
projectile.cpp
projectile::projectile()
{
x = 0.0f;
y = 0.0f;
}
projectile::projectile(float X, float Y)
{
x = X;
y = Y;
}
float projectile::get_x() const
{
return x;
}
float projectile::get_y() const
{
return y;
}
void projectile::move()
{
x += 0.5f;
y += 0.5f;
}
asteroid.h
#include "projectile.h"
class asteroid : public projectile
{
float radius;
public:
asteroid();
asteroid(float X, float Y);
float get_radius();
};
main.cpp
#include <iostream>
#include "asteroid.h"
using namespace std;
int main()
{
asteroid a(1.0f, 2.0f);
cout << a.get_x() << endl;
cout << a.get_y() << endl;
}
error I'm getting:
main.cpp:(.text+0x20): undefined reference to `asteroid::asteroid(float, float)'
You can use the : syntax to call the parent's constructor:
asteroid(float X, float Y) : projectile (x ,y);
Ok, just figured it out.
I actually don't have asteroid constructors defined because I thought they would inherit. But I think I have to do the following in asteroid.h:
asteroid(float X, float Y) : projectile(X, Y){];
You need a asteroid.cpp.
Even though inheriting from projectile, for non-default constructors (i.e., asteroid(float,float)), you still need to define the child class constructor.
You'll also need to define get_radius, as it's not defined in your base class.
Here's how that might look (I've taken the liberty of passing values for radius into both ctors):
#include "asteroid.h"
asteroid::asteroid(float r)
: projectile()
{
radius = r;
}
asteroid::asteroid(float x, float y, float r)
: projectile(x, y)
{
radius = r;
}
float asteroid::get_radius()
{
return radius;
}

Draw function timer openframeworks

How can I, using the draw() function of openframeworks, draw a square - ofRect (x, y, w, h) for x in x seconds?
I know it is possible since the draw uses fps but I do not know how to manipulate in order to do what I want.
Thank you!
One option is to interpolate based on time, not frame count using ofGetElapsedTimeMillis()
Another is to use a tweening/animation addon. You can find quite a few on ofxAddons in the animation section
You could do that in the simplest way:
int x = ofGetElapsedTimeMillis();
int y = 10;
int w = 100;
int h = 100;
ofDrawRectangle(x, y, w, h);
Note that in OpenFrameworks you should use ofDrawRectangle, it is different from ofRectangle.
If you want to reach more adivanced animations, I would recommend you to use ofxTweenzor addon, where you can manipulate variables in a period of time like this:
.h file:
#include "ofMain.h"
#include "ofxTweenzor.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
float x1;
};
.cpp file:
#include "testApp.h"
void ofApp::setup() {
Tweenzor::init();
float initialX = 0.f;
float finalX = 900.f;
float delay = 0.0f;
float durationInSeconds = 1.f;
Tweenzor::add(&x, initialX, finalX, delay, durationInSeconds );
}
void ofApp::update(){
Tweenzor::update( ofGetElapsedTimeMillis() );
}
void ofApp::draw() {
int y = 10;
int w = 100;
int h = 100;
ofDrawRectangle(x, y, w, h);
}

C++ Sprite class with Vector Object as Member

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.