How to make an increment followed by a decrement continuously? - c++

I am trying to obtain an increment that goes up from 0 to n, then decreases from n-1 to 0, and repeats the cycle over and over.
In this example written in Processing, I would like the background to go from black(i=0) to white(i=255) incrementally then white to black incrementally and so forth. Now I only get it to go from black to white, and then it comes back to black suddenly.
int i = 0;
void setup(){
size(640, 360);
frameRate(60);
}
void draw(){
background(i);
i++;
if(i==256){i=0;}
}

Try -
int change = 1;
void draw(){
background(i);
i = i + change;
if(i==256){change = -1;}
if(i==0){change = 1;}
}

Another way to look at this question would be: "How could I draw a triangle wave?".
I like this way cause it does not need "ifs". Some thing like this would do.
triangleWave = maxNumber - abs(incrementedVar % (2*maxNumber) - maxNumber);
Coll, isn't it?
I have this old code using this, it's not drawing the wave, but using it for size and fill color. Also there is a sine wave for comparision. Check it out:
float zigZag, toIncrement, speed =1, maxNumber = 255;
float sine, x = 270, speed2 = 1;
void setup() {
size(800, 400);
background(255);
}
void draw() {
background(255);
//triangle wave
toIncrement+=speed;
zigZag = maxNumber - abs(toIncrement % (2*maxNumber) - maxNumber);
fill(zigZag);
noStroke();
ellipse( 150, height/2+100, 50, 50);
strokeWeight(zigZag);
stroke(0);
line(100, height/2-100, 200, height/2-100);
text("triangle = " + int(zigZag), 100, height-30);
println("triangle wave value = " + zigZag);
//sine wave
x+=speed2;
sine = (1+sin(radians(x)))*(maxNumber/2);
fill(sine);
noStroke();
ellipse( 650, height/2+100, 50, 50);
strokeWeight(sine);
stroke(0);
line(600, height/2-100, 700, height/2-100);
fill(80);
text("sine = " + int(sine), 600, height-30);
}

Related

Detect specific angle in image with OpenCV

I'm currently developing an application that takes images and detect a specific angle in that image.
The images always look something like this: original image.
I want to detect the angle of the bottom cone.
In order to do that i crop that image in image and use two Houghline algorithms. One for the cone and one for the table at the bottom. This works failry well and i get the correct result in 90% of the images.
result of the two algorithms
Doesnt work
Doesnt work either
My approach works for now because i can guarantee that the cone will alwys be in an angle range of 5 to 90°. So i can filter the houghlines based on their angle.
However i wonder if their is a better approach to this. This is my first time working with OpenCV, so maybe this community has some tips to improve the whole thing. Any help is appreciated!
My code for the cone so far:
public (Bitmap bmp , double angle) Calculate(Mat imgOriginal, Mat imgCropped, int Y)
{
Logging.Log("Functioncall: Calculate");
var finalAngle = 0.0;
Mat imgWithLines = imgOriginal.Clone();
how croppedImage look's
var grey = new Mat();
CvInvoke.CvtColor(imgCropped, grey, ColorConversion.Bgr2Gray);
var bilateral = new Mat();
CvInvoke.BilateralFilter(grey, bilateral, 15, 85, 15);
var blur = new Mat();
CvInvoke.GaussianBlur(bilateral, blur, new Size(5, 5), 0); // Kernel reduced from 31 to 5
var edged = new Mat();
CvInvoke.Canny(blur, edged, 0, 50);
var iterator = true;
var counter = 0;
var hlThreshhold = 28;
while (iterator &&counter<40)
{
counter++;
var threshold = hlThreshhold;
var rho = 1;
var theta = Math.PI / 180;
var lines = new VectorOfPointF();
CvInvoke.HoughLines(edged, lines, rho, theta, threshold);
var angles = CalculateAngles(lines);
if (angles.Length > 1)
{
hlThreshhold += 1;
}
if (angles.Length < 1)
{
hlThreshhold -= 1;
}
if (angles.Length == 1)
{
try
{
//Calc the more detailed position of glassLine and use it for Calc with ConeLine instead of perfect horizontal line
var glassLines = new VectorOfPointF();
var glassTheta = Math.PI / 720; // accuracy: PI / 180 => 1 degree | PI / 720 => 0.25 degree |
CvInvoke.HoughLines(edged, glassLines, rho, glassTheta, threshold);
var glassEdge = CalculateGlassEdge(glassLines);
iterator = false;
// finalAngle = angles.FoundAngle; // Anzeige der Winkel auf 2 Nachkommastellen
CvInvoke.Line(imgWithLines, new Point((int)angles.LineCoordinates[0].P1.X, (int)angles.LineCoordinates[0].P1.Y + Y), new Point((int)angles.LineCoordinates[0].P2.X, (int)angles.LineCoordinates[0].P2.Y + Y), new MCvScalar(0, 0, 255), 5);
CvInvoke.Line(imgWithLines, new Point((int)glassEdge.LineCoordinates[0].P1.X, (int)glassEdge.LineCoordinates[0].P1.Y + Y), new Point((int)glassEdge.LineCoordinates[0].P2.X, (int)glassEdge.LineCoordinates[0].P2.Y + Y), new MCvScalar(255, 255, 0), 5);
// calc Angle ConeLine and GlassLine
finalAngle = 90 + angles.LineCoordinates[0].GetExteriorAngleDegree(glassEdge.LineCoordinates[0]);
finalAngle = Math.Round(finalAngle, 1);
//Calc CrossPoint
PointF crossPoint = getCrossPoint(angles.LineCoordinates[0], glassEdge.LineCoordinates[0]);
//Draw dashed Line through crossPoint
drawDrashedLineInCrossPoint(imgWithLines, crossPoint, 30);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
finalAngle = 0.0;
imgWithLines = imgOriginal.Clone();
}
}
}
Image cropping (the table is always on the same position, so i use this position and a height parameter to only get the bottom of the cone )
public Mat ReturnCropped(Bitmap imgOriginal, int GlassDiscLine, int HeightOffset)
{
var rect = new Rectangle(0, 2500-GlassDiscLine-HeightOffset, imgOriginal.Width, 400);
return new Mat(imgOriginal.ToMat(), rect);
}

SFML slow when drawing more than 500 shapes

I am new to SFML and I would like to implement a fluid boids simulation. However, I realized that when more than 500 shapes are drawn at the same time, the fps drop quickly.
How can I improve the code below to make it much faster to run?
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
sf::ConvexShape newShape() {
sf::ConvexShape shape(3);
shape.setPoint(0, sf::Vector2f(0, 0));
shape.setPoint(1, sf::Vector2f(-7, 20));
shape.setPoint(2, sf::Vector2f(7, 20));
shape.setOrigin(0, 10);
shape.setFillColor(sf::Color(49, 102, 156, 150));
shape.setOutlineColor(sf::Color(125, 164, 202, 150));
shape.setOutlineThickness(1);
shape.setPosition(rand() % 800, rand() % 600);
shape.setRotation(rand() % 360);
return shape;
}
int main() {
sf::Clock dtClock, fpsTimer;
sf::RenderWindow window(sf::VideoMode(800, 600), "Too Slow");
std::vector<sf::ConvexShape> shapes;
for (int i = 0; i < 1000; i++) shapes.push_back(newShape());
while (window.isOpen()) {
window.clear(sf::Color(50, 50, 50));
for (auto &shape : shapes) { shape.rotate(0.5); window.draw(shape); }
window.display();
float dt = dtClock.restart().asSeconds();
if (fpsTimer.getElapsedTime().asSeconds() > 1) {
fpsTimer.restart();
std::cout << ((1.0 / dt > 60) ? 60 : (1.0 / dt)) << std::endl;
}
}
}
I have the following performance:
Shapes FPS
10 60
100 60
500 60
600 60
700 55
800 50
900 45
1000 21
My goal is to have about 5k boids on the screen.
EDIT
I am building the project on Windows 11 under WSL2 with vGPU enabled. When testing natively on Windows 11 with Visual Studio I get much better performance (I can run 5k boids at 60 FPS)
The problems are a lot of draw calls. That is slow part of this program. In order to fix this, we can put all triangles into single vertex array and call draw upon only that array. That way we will speed up program. Problem with it is that you must implement your own rotate method. I implemented the method below and edited so the function returns triangles in single vertex array.
#include <SFML/Graphics.hpp>
#include <iostream>
//This function returns vertex array by given number of triangles
sf::VertexArray newShape(int numberOfTriangles) {
sf::VertexArray shape(sf::Triangles);
//we are going trough every point in each triangle
for (int i=0;i<3*numberOfTriangles;i++){
//creating points of triangles as vertexes 1, 2 and 3
sf::Vertex v1(sf::Vector2f(rand() % 800, rand() % 600));
sf::Vertex v2(sf::Vector2f(v1.position.x - 7, v1.position.y - 20));
sf::Vertex v3(sf::Vector2f(v1.position.x + 7, v1.position.y - 20));
//setting color
v1.color = v2.color = v3.color = sf::Color(49, 102, 156, 150);
//rotating for random angle
sf::Transform transform;
transform.rotate(rand()%90, (v2.position.x + v3.position.x) / 2,v1.position.y - 10);
v1.position = transform.transformPoint(v1.position);
v2.position = transform.transformPoint(v2.position);
v3.position = transform.transformPoint(v3.position);
//appending them into vertex array
shape.append(v1);
shape.append(v2);
shape.append(v3);
}
return shape;
}
//rotate function finds the middle of 3 vertexes and rotates them
void rotate(sf::VertexArray& array, double angle){
for (int i=0;i<array.getVertexCount();i+=3){
sf::Transform transform;
transform.rotate(angle, (array[i+1].position.x + array[i+2].position.x) / 2, (array[i].position.y + array[i+1].position.y)/2);
array[i].position = transform.transformPoint(array[i].position);
array[i+1].position = transform.transformPoint(array[i+1].position);
array[i+2].position = transform.transformPoint(array[i+2].position);
}
}
int main() {
sf::Clock dtClock, fpsTimer;
sf::RenderWindow window(sf::VideoMode(800, 600), "Too Slow");
//creating new array with 30000 triangles
sf::VertexArray shapes = newShape(30000);
window.setFramerateLimit(60);
while (window.isOpen()) {
//event to close window on close button
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear(sf::Color(50, 50, 50));
//no need for for now, as you can rotate them all in function and draw them together
rotate(shapes,5);
window.draw(shapes);
window.display();
float dt = dtClock.restart().asSeconds();
if (fpsTimer.getElapsedTime().asSeconds() > 1) {
fpsTimer.restart();
std::cout << ((1.0 / dt > 60) ? 60 : (1.0 / dt)) << std::endl;
}
}
}
The bottleneck now is not drawing but rotating, i tested this code with 100000 triangles and im getting around 45 fps. With 1000000 i am getting bad framerate because of rotation.

Low framerate with only map and minimap drawing (SFML)

I'm working on a small "game" like project as a practice, and I've managed to get my framerate down to not even 3 FPS. While the only thing that is being drawn is screen filling tiles and a minimap.
Now I've found that the problem is with the minimap, without it caps at 60 FPS. But unfortunately I'm not experienced enough to find out what the real problem is with it...
My draw function:
void StateIngame::draw()
{
m_gui.removeAllWidgets();
m_window.setView(m_view);
// Frame counter
float ct = m_clock.restart().asSeconds();
float fps = 1.f / ct;
m_time = ct;
char c[10];
sprintf(c, "%f", fps);
std::string fpsStr(c);
sf::String str(fpsStr);
auto fpsText = tgui::Label::create();
fpsText->setText(str);
fpsText->setTextSize(16);
fpsText->setPosition(15, 15);
m_gui.add(fpsText);
//////////////
// Draw map //
//////////////
int camOffsetX, camOffsetY;
int tileSize = m_map.getTileSize();
Tile tile;
sf::IntRect bounds = m_camera.getTileBounds(tileSize);
camOffsetX = m_camera.getTileOffset(tileSize).x;
camOffsetY = m_camera.getTileOffset(tileSize).y;
// Loop and draw each tile
// x and y = counters, tileX and tileY is the coordinates of the tile being drawn
for (int y = 0, tileY = bounds.top; y < bounds.height; y++, tileY++)
{
for (int x = 0, tileX = bounds.left; x < bounds.width; x++, tileX++)
{
try {
// Normal view
m_window.setView(m_view);
tile = m_map.getTile(tileX, tileY);
tile.render((x * tileSize) - camOffsetX, (y * tileSize) - camOffsetY, &m_window);
} catch (const std::out_of_range& oor)
{}
}
}
bounds = sf::IntRect(bounds.left - (bounds.width * 2), bounds.top - (bounds.height * 2), bounds.width * 4, bounds.height * 4);
for (int y = 0, tileY = bounds.top; y < bounds.height; y++, tileY++)
{
for (int x = 0, tileX = bounds.left; x < bounds.width; x++, tileX++)
{
try {
// Mini map
m_window.setView(m_minimap);
tile = m_map.getTile(tileX, tileY);
sf::RectangleShape miniTile(sf::Vector2f(4, 4));
miniTile.setFillColor(tile.m_color);
miniTile.setPosition((x * (tileSize / 4)), (y * (tileSize / 4)));
m_window.draw(miniTile);
} catch (const std::out_of_range& oor)
{}
}
}
// Gui
m_window.setView(m_view);
m_gui.draw();
}
The Tile class has a variable of type sf::Color which is set during map generating. This color is then used to draw the minimap instead of the 16x16 texture that is used for the map itself.
So when I leave out the minimap drawing, and only draw the map itself, it's more fluid than I could wish for...
Any help is appreciated!
You are generating the view completly new for every frame. Do this once on startup should be enought.

Pixel Perfect Collision Detection in Cocos2dx

I am trying to port the pixel perfect collision detection in Cocos2d-x the original version was made for Cocos2D and can be found here: http://www.cocos2d-iphone.org/forums/topic/pixel-perfect-collision-detection-using-color-blending/
Here is my code for the Cocos2d-x version
bool CollisionDetection::areTheSpritesColliding(cocos2d::CCSprite *spr1, cocos2d::CCSprite *spr2, bool pp, CCRenderTexture* _rt) {
bool isColliding = false;
CCRect intersection;
CCRect r1 = spr1->boundingBox();
CCRect r2 = spr2->boundingBox();
intersection = CCRectMake(fmax(r1.getMinX(),r2.getMinX()), fmax( r1.getMinY(), r2.getMinY()) ,0,0);
intersection.size.width = fmin(r1.getMaxX(), r2.getMaxX() - intersection.getMinX());
intersection.size.height = fmin(r1.getMaxY(), r2.getMaxY() - intersection.getMinY());
// Look for simple bounding box collision
if ( (intersection.size.width>0) && (intersection.size.height>0) ) {
// If we're not checking for pixel perfect collisions, return true
if (!pp) {
return true;
}
unsigned int x = intersection.origin.x;
unsigned int y = intersection.origin.y;
unsigned int w = intersection.size.width;
unsigned int h = intersection.size.height;
unsigned int numPixels = w * h;
//CCLog("Intersection X and Y %d, %d", x, y);
//CCLog("Number of pixels %d", numPixels);
// Draw into the RenderTexture
_rt->beginWithClear( 0, 0, 0, 0);
// Render both sprites: first one in RED and second one in GREEN
glColorMask(1, 0, 0, 1);
spr1->visit();
glColorMask(0, 1, 0, 1);
spr2->visit();
glColorMask(1, 1, 1, 1);
// Get color values of intersection area
ccColor4B *buffer = (ccColor4B *)malloc( sizeof(ccColor4B) * numPixels );
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
_rt->end();
// Read buffer
unsigned int step = 1;
for(unsigned int i=0; i 0 && color.g > 0) {
isColliding = true;
break;
}
}
// Free buffer memory
free(buffer);
}
return isColliding;
}
My code is working perfectly if I send the "pp" parameter as false. That is if I do only a bounding box collision but I am not able to get it working correctly for the case when I need Pixel Perfect collision.
I think the opengl masking code is not working as I intended.
Here is the code for "_rt"
_rt = CCRenderTexture::create(visibleSize.width, visibleSize.height);
_rt->setPosition(ccp(origin.x + visibleSize.width * 0.5f, origin.y + visibleSize.height * 0.5f));
this->addChild(_rt, 1000000);
_rt->setVisible(true); //For testing
I think I am making a mistake with the implementation of this CCRenderTexture
Can anyone guide me with what I am doing wrong ?
Thank you for your time :)
Finally solved the problem.
Had to use custom opengl fragment shaders to shade one of the sprites completely RED and the other completely BLUE and then looping through glReadPixels values to find any pixel having both RED and BLUE pixels. (Blending has to be considered as well, we do not want to replace one pixel value by the other)
In-Depth information can be found on my blog post
http://blog.muditjaju.infiniteeurekas.in/?p=1
You are not stepping through the buffer properly.
// Read buffer
unsigned int step = 1;
for(unsigned int i=0; i<numPixels; i+=step)
{
ccColor4B color = buffer;
if (color.r > 0 && color.g > 0)
{
isCollision = YES;
break;
}
}
source: http://www.cocos2d-iphone.org/forums/topic/pixel-perfect-collision-detection-using-color-blending/#post-337907

2D water shader in SFML

I want to implement the algorithm for a 2D water surface described here and here.
But instead of using two int arrays and calculating on the CPU I would like to use SFML's sf::RenderTexture's (FBO's basically) and a GLSL shader to run everything on the GPU. I want to use SFML, because it's so simple and I have worked with it before, so I know my way around it a little.
I've made some good progress so far. I was able to set up 3 sf::RenderTextures and ping-pong between them correctly (because other than int array you can't read and write to the same sf::RenderTexture at the same time). I was also able to adapt the algorithm for the height field creation form being in the range -32.767 to 32.767 to the range 0 to 1 (or to be more precise -0.5 to 0.5 for the calculation). Also adding new ripples works to some extend. So up to this point you can actually see a little of waves going on.
Here comes my problem now: The waves disappear really, really fast and I don't even apply any damping yet. According to the algorithm the ripples are not stopping if there is no damping applied. It's even the other way around. If I apply "amplification" the waves look close to what you would expect them to look like (but they still disappear without any damping applied to them). My first thought was that this is, because I use float's in range 0 - 1 instead of integers, but I only see this being a problem if multiplication is used, but I only use addition and subtraction.
Here is my SFML C++ code :
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(1000, 1000), "SFML works!");
window.setFramerateLimit(12);
sf::RenderTexture buffers[3];
buffers[0].create(500, 500);
buffers[1].create(500, 500);
buffers[2].create(500, 500);
sf::RenderTexture* firstBuffer = buffers;
sf::RenderTexture* secondBuffer = &buffers[1];
sf::RenderTexture* finalBuffer = &buffers[2];
firstBuffer->clear(sf::Color(128, 128, 128));
secondBuffer->clear(sf::Color(128, 128, 128));
finalBuffer->clear(sf::Color(128, 128, 128));
sf::Shader waterHeightmapShader;
waterHeightmapShader.loadFromFile("waterHeightmapShader.glsl", sf::Shader::Fragment);
sf::Sprite spritefirst;
spritefirst.setPosition(0, 0);
spritefirst.setTexture(firstBuffer->getTexture());
sf::Sprite spritesecond;
spritesecond.setPosition(500, 0);
spritesecond.setTexture(secondBuffer->getTexture());
sf::Sprite spritefinal;
spritefinal.setPosition(0, 500);
spritefinal.setTexture(finalBuffer->getTexture());
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
if(event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Escape)
window.close();
}
waterHeightmapShader.setParameter("mousePosition", sf::Vector2f(-1.f, -1.f));
// if mouse button is pressed add new ripples
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sf::Vector2i mousePosition = sf::Mouse::getPosition(window);
if(mousePosition.x < 500 && mousePosition.y < 500)
{
sf::Vector2f mouse(mousePosition);
mouse.x /= 500.f;
mouse.y /= 500.f;
mouse.y = 1 - mouse.y;
std::cout << mouse.x << " " << mouse.y << std::endl;
waterHeightmapShader.setParameter("mousePosition", mouse);
}
}
waterHeightmapShader.setParameter("textureTwoFramesAgo", firstBuffer->getTexture());
waterHeightmapShader.setParameter("textureOneFrameAgo", secondBuffer->getTexture());
// create the heightmap
secondBuffer->display();
finalBuffer->clear(sf::Color(128, 128, 128));
finalBuffer->draw(sf::Sprite(secondBuffer->getTexture()), &waterHeightmapShader);
finalBuffer->display();
spritefirst.setTexture(firstBuffer->getTexture());
spritesecond.setTexture(secondBuffer->getTexture());
spritefinal.setTexture(finalBuffer->getTexture());
window.clear();
window.draw(spritefirst);
window.draw(spritesecond);
window.draw(spritefinal);
window.display();
// swap the buffers around, first becomes second, second becomes third and third becomes first
sf::RenderTexture* swapper = firstBuffer;
firstBuffer = secondBuffer;
secondBuffer = finalBuffer;
finalBuffer = swapper;
}
return 0;
}
And here is my GLSL shader code :
uniform sampler2D textureTwoFramesAgo;
uniform sampler2D textureOneFrameAgo;
uniform vec2 mousePosition;
const float textureSize = 500.0;
const float pixelSize = 1.0 / textureSize;
void main()
{
// pixels position
vec2 position = gl_TexCoord[0].st;
vec4 finalColor = ((texture2D(textureOneFrameAgo, vec2(position.x - pixelSize, position.y)) +
texture2D(textureOneFrameAgo, vec2(position.x + pixelSize, position.y)) +
texture2D(textureOneFrameAgo, vec2(position.x, position.y + pixelSize)) +
texture2D(textureOneFrameAgo, vec2(position.x, position.y - pixelSize)) - 2.0) / 2) -
(texture2D(textureTwoFramesAgo, position) - 0.5);
// damping
// finalColor.rgb *= 1.9; // <---- uncomment this for the "amplifiction" ie. to see the waves better
finalColor.rgb += 0.5;
// add new ripples
if(mousePosition.x > 0.0)
{
if(distance(position, mousePosition) < pixelSize * 5)
{
finalColor = vec4(0.9, 0.9, 0.9, 1.0);
}
}
gl_FragColor = finalColor;
}
Please remember that this is all just about the height field creation. There is no shading of the water yet.
Do you know why the waves disappear by them self without damping?
If I am reading the code correctly you sample the previous frame for the texture's colors/height and use four neighboring pixels/texels to determine the color/height of the current pixel.
As you are calculating (scaling) these neighbors you might run into missing the texel that contains the color/height you are looking for. It might not be the heighest texel, just one next to it a little bit lower causing the unexpected damping.
This is where you do not just use addition and subtraction:
const float pixelSize = 1.0 / textureSize;
By using this value you could just miss the texel you are looking for.
EDIT
Also: you are averaging the samples so the result will always be less than the maximum value of the samples. So instead of averaging you could select the maximum value. That might give weird results but also extra insight.
Here are some "Processing" codes which implements the same algorithm you've posted above, and its damping is correct, I hope you can get some points from it :
// codes begin
int Width = 800;
int Height = 600;
int FullSize = 0;
//int Spacing = 10;
int[] source, dest;
PImage bg;
void setup()
{
// if you want to run these codes by "Processing"
// please make a picture named "HelloWorld.png"
bg = loadImage("HelloWorld.png");
Width = bg.width;
Height = bg.height;
FullSize = Width * Height;
size(Width, Height);
source = new int[FullSize];
dest = new int[FullSize];
for (int i=0; i< FullSize; i++)
source[i] = dest[i] = 0;
}
void draw()
{
for (int i=Width; i< FullSize-Width; i++)
{
// check for bounds
int xi = i % Width;
if ((xi==0) || (xi==Width-1)) continue;
dest[i] = (
((source[i-1]+
source[i+1]+
source[i-Width]+
source[i+Width]) >>1) ) -dest[i];
int dampFactor = 1000;
dest[i] -= (dest[i] >> dampFactor); // Damping - Quick divde by 32 (5 bits)
}
//image(bg, 0, 0);
loadPixels();
for (int i=Width; i< FullSize-Width; i++)
{
// check for bounds
int xi = i % Width;
if ((xi==0) || (xi==Width-1)) continue;
int xoffset = dest[i-1] - dest[i+1];
int yoffset = dest[i-Width] - dest[i+Width];
int offset = i+xoffset+yoffset*Width;
if (offset>0 && offset<FullSize)
{
// TODO: make better map
pixels[i] = bg.pixels[offset];
}
}
//bg.updatePixels();
updatePixels();
//swap
int[] temp = source;
source = dest;
dest = temp;
}
void mouseDragged()
{
if (mouseX > 0 && mouseX < Width && mouseY > 0 && mouseY < Height)
source[mouseY*Width+mouseX] = (int)random(50, 100);
}
void mousePressed()
{
// TODO: make a area pulse value, like a radius circle
if (mouseX > 0 && mouseX < Width && mouseY > 0 && mouseY < Height)
source[mouseY*Width+mouseX] = (int)random(50, 100);
}
// codes end