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);
}
Related
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);
};
Hello I am a student learning c++ and I am just starting to learn OOP. The problem is in my MAIN however I am showing all of my files in case it is from another file.
I have written my hpp and cpp file and now I am just working on my main for testing. The class is called Box and when I create an object box1 or box 2 and attempt to access my functions it says there are two few arguments. It says this regardless of whether I put box1.calcVolume(double h, double w, double l) or box1.calcVolume();
So the issue is on the line(s) that say:
double volume2 = box2.calcVolume();
double volume1 = box1.calcVolume();
double surfaceArea1 = box1.calcSurfaceArea();
If anyone can spot something that I missing our may not understand please let me know.
This is the header file:
#pragma once
#include <iostream>
#ifndef BOX_HPP
#define BOX_HPP
class Box
{
private:
double height;
double width;
double length;
public:
void setHeight(double h);
void setWidth(double w);
void setLength(double l);
double calcVolume(double h, double w, double l);
double calcSurfaceArea(double h, double w, double l);
Box();
Box(double height, double width, double length);
};
#endif
This is the CPP file
#include <iostream>
#include "Box.hpp"
Box::Box()
{
setHeight(1);
setWidth(1);
setLength(1);
}
Box::Box(double h, double w, double l)
{
setHeight(h);
setWidth(w);
setLength(l);
}
void Box::setHeight(double h)
{
height = h;
}
void Box::setWidth(double w)
{
width = w;
}
void Box::setLength(double l)
{
length = l;
}
double Box::calcVolume(double h, double w, double l)
{
double volume;
volume = h * w * l;
return volume;
}
double Box::calcSurfaceArea(double h, double w, double l)
{
double surfaceArea;
surfaceArea = 2 * (h*w) + 2 * (h*l) + 2 * (l*w);
return surfaceArea;
}
my BoxMain file:
#include <iostream>
#include "Box.hpp"
using std::cout;
using std::cin;
using std::endl;
int main()
{
Box box1(1.1, 2.4, 3.8);
Box box2;
box2.setHeight(12);
box2.setWidth(22.3);
box2.setLength(2.3);
double volume2 = box2.calcVolume();
double volume1 = box1.calcVolume();
double surfaceArea1 = box1.calcSurfaceArea();
cout << box1.calcVolume(); << endl; //testing different methods
return 0;
}
Your method takes three parameters:
double Box::calcVolume(double h, double w, double l)
{
double volume;
volume = h * w * l;
return volume;
}
So, you would call it like so:
Box b;
double volume = b.calcVolume(1, 2, 3);
But that's not quite right. An instance of Box knows how big it is, because you pass a size to the constructor, which stores the sizes in the fields width, height, and length. You probably want something like this:
double Box::calcVolume()
{
volume = height * width * length;
return volume;
}
You have the code wrong. The dimensions of the box are known during the creation of box object. The length, width and height are already available - updated in the member variables.
Functions calcVolume and calcSurfaceArea should not take arguments but return the computed value. Modified code below:
double Box::calcVolume()
{
return height*width*length;
}
double Box::calcSurfaceArea()
{
return 2*((height*width) + (height*length) + (length*width));
}
Also, remember to modify the .hpp file with the declarations corresponding to the code above.
Declaration in the .hpp file should be
double calcVolume();
double calcSurfaceArea();
I have solved the problem. I removed the arguments in calcVolume and calcSurfaceArea everywhere in my code and it resolved the error.
I'm trying to achieve polymorphism with my image manipulation program. I keep getting this error, I think it is caused from me defining scale twice in both the header file and the cpp file.
Error C2011 'scale': 'class' type redefinition
and I am not sure what to do. Thanks for any help.
.cpp file
Image *begin= new Image(750, 750);
begin->read("picture1.jpg");
Image *enlarged= new Image(1500, 1500);
scale *pass= new scale(*imgScale);
pass->manipulator(1500, 1500);
pass->load("manipulated.jpg");
class scale : public Image
{
public:
scale(Image const &firstimg)
{
w = firstimg.w;
h = firstimg.h;
pixels = firstimg.pixels;
}
void manipulator(int w2, int h2)
{
Image *temp = new Image(w2, h2);
float x_ratio = (float )w / w2;
float y_ratio = (float )h / h2;
float px, py;
for (int i = 0; i < h2; i++)
{
for (int j = 0; j < w2; j++)
{
px = floor(j*x_ratio);
py = floor(i*y_ratio);
temp->pixels[(i*w2) + j] = this->pixels[(int)((py*w) + px)];
}
}
}
};
header file
#pragma once
#ifndef manipulator_H
#define manipulator_H
class scale : public Image
{
public:
scale(Image const &firstimg);
void manipulator(int w2, int h2);
};
#endif
You are declaring you class Scale in two different files, in the algo header file and in the .cpp file. Actually, I don't know why are how using inheritance if you are creating a new Image in your zoom function.
Your header, scale.h should be something like that:
#pragma once
#ifndef ALGORITHMS_H
#define ALGORITHMS_H
class Image;
class Scale {
public:
explicit Scale(Image const &beginImg);
void zoom(int w2, int h2);
private:
// Here all your private variables
int w;
int h;
¿? pixels;
};
#endif
And your cpp file, scale.cpp:
#include "scale.h"
#include "image.h"
Scale::Scale(Image const &beginImg) :
w(beginImg.w),
h(beginImg.h),
pixels(beginImg.pixels) {}
void Scale::zoom(int w2, int h2){
Image *temp = new Image(w2, h2);
double x_ratio = (double)w / w2;
double y_ratio = (double)h / h2;
double px, py;
// rest of your code;
}
And, then in the place you want to use this class, example your main:
int main() {
Image *imgScale = new Image(750, 750);
imgScale->readPPM("Images/Zoom/zIMG_1.ppm");
Scale *test = new Scale(*imgScale);
test->zoom(1500, 1500);
test->writePPM("Scale_x2.ppm");
delete imgScale;
delete test;
return 0;
}
In any case, consider using smart pointers instead of raw pointers and take a look in to the different modifications I did.
I have two simple files. Ball.h and Ball.cpp.
When I compile my program, I get the error "one or more multiply defined symbols" for the variables int x and int y.
I understand that if I make those variables static, the error will go away, I do not understand why. I'm sorry if this is duplicate, but I could not understand the explanations that I have read elsewhere.
I have another class "Player" that also use int x and int y variables. Is that the cause of the issue?
Ball.cpp:
#include <SDL.h>
#include "Ball.h"
const int BALL_SIZE = 20;
static int dx, dy;
static int x, y;
void Ball::Init(){
x = 320;
y = 240;
dx = 1;
dy = 1;
}
void Ball::Tick(){
x += dx;
y += dy;
}
void Ball::Render(SDL_Renderer* render){
}
void Ball::ReverseVelocity(){
}
Ball.h
#include <SDL.h>
class Ball{
public:
void Init();
void Tick();
void Render(SDL_Renderer* render);
void ReverseVelocity();
};
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.