/******************************************************* * Copyright (c) 2014, ArrayFire * All rights reserved. * * This file is distributed under 3-clause BSD license. * The complete license agreement can be obtained at: * http://arrayfire.com/licenses/BSD-3-Clause ********************************************************/ #include #include #include using namespace af; using namespace std; static const int width = 512, height = 512; static const int pixels_per_unit = 20; void simulate(af::array *pos, af::array *vels, af::array *forces, float dt){ pos[0] += vels[0] * pixels_per_unit * dt; pos[1] += vels[1] * pixels_per_unit * dt; //calculate distance to center af::array diff_x = pos[0] - width/2; af::array diff_y = pos[1] - height/2; af::array dist = sqrt( diff_x*diff_x + diff_y*diff_y ); //calculate normalised force vectors forces[0] = -1 * diff_x / dist; forces[1] = -1 * diff_y / dist; //update force scaled to time and magnitude constant forces[0] *= pixels_per_unit * dt; forces[1] *= pixels_per_unit * dt; //dampening vels[0] *= 1 - (0.005*dt); vels[1] *= 1 - (0.005*dt); //update velocities from forces vels[0] += forces[0]; vels[1] += forces[1]; } void collisions(af::array *pos, af::array *vels){ //clamp particles inside screen border af::array projected_px = min(width, max(0, pos[0])); af::array projected_py = min(height - 1, max(0, pos[1])); //calculate distance to center af::array diff_x = projected_px - width/2; af::array diff_y = projected_py - height/2; af::array dist = sqrt( diff_x*diff_x + diff_y*diff_y ); //collide with center sphere const int radius = 50; const float elastic_constant = 0.91f; if(sum(dist 0) { vels[0](dist