X-Git-Url: https://fleuret.org/cgi-bin/gitweb/gitweb.cgi?p=flatland.git;a=blobdiff_plain;f=polygon.cc;h=b8999503e3c14cec184aa0820c33574da269bd60;hp=69b125eb789e86e3ec798b0edbd139d1f1e5d081;hb=c99cbb5f30e1e2052bfc36880a1425db600454b5;hpb=26abc735ca75a78974c7ced091035e8c27ca1c00 diff --git a/polygon.cc b/polygon.cc index 69b125e..b899950 100644 --- a/polygon.cc +++ b/polygon.cc @@ -1,26 +1,26 @@ /* - * dyncnn is a deep-learning algorithm for the prediction of - * interacting object dynamics - * - * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ - * Written by Francois Fleuret - * - * This file is part of dyncnn. - * - * dyncnn is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 3 as - * published by the Free Software Foundation. - * - * dyncnn is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with dyncnn. If not, see . - * - */ + + flatland is a simple 2d physical simulator + + Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ + Written by Francois Fleuret + + This file is part of flatland + + flatland is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License version 3 as + published by the Free Software Foundation. + + flatland is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with flatland. If not, see . + +*/ #include @@ -31,7 +31,8 @@ using namespace std; static const scalar_t dl = 20.0; static const scalar_t repulsion_constant = 0.2; -static const scalar_t dissipation = 0.5; +static const scalar_t speed_max = 1e2; +static const scalar_t angular_speed_max = M_PI / 10; Polygon::Polygon(scalar_t mass, scalar_t red, scalar_t green, scalar_t blue, @@ -306,17 +307,27 @@ void Polygon::initialize(int nb_polygons) { } bool Polygon::update(scalar_t dt) { + scalar_t speed = sqrt(_dcenter_x * _dcenter_x + _dcenter_y * _dcenter_y); + + if(speed > 0) { + scalar_t speed_target = speed_max - exp(-speed / speed_max) * speed_max; + _dcenter_x = speed_target * _dcenter_x / speed; + _dcenter_y = speed_target * _dcenter_y / speed; + } + + scalar_t angular_speed = abs(_dtheta); + + if(angular_speed > 0) { + scalar_t angular_speed_target = angular_speed_max - exp(-angular_speed / angular_speed_max) * angular_speed_max; + _dtheta = angular_speed_target * _dtheta / angular_speed; + } + if(!_nailed) { _center_x += _dcenter_x * dt; _center_y += _dcenter_y * dt; _theta += _dtheta * dt; } - scalar_t d = exp(log(dissipation) * dt); - _dcenter_x *= d; - _dcenter_y *= d; - _dtheta *= d; - scalar_t vx = cos(_theta), vy = sin(_theta); for(int n = 0; n < _nb_vertices; n++) { @@ -356,7 +367,9 @@ void Polygon::apply_force(scalar_t dt, scalar_t x, scalar_t y, scalar_t fx, scal _dtheta -= prod_vect(x - _center_x, y - _center_y, fx, fy) / (_mass * _moment_of_inertia) * dt; } -void Polygon::apply_border_forces(scalar_t dt, scalar_t xmax, scalar_t ymax) { +void Polygon::apply_border_forces(scalar_t dt, + scalar_t xmin, scalar_t ymin, + scalar_t xmax, scalar_t ymax) { for(int v = 0; v < _nb_vertices; v++) { int vp = (v+1)%_nb_vertices; for(int d = 0; d < _nb_dots[v]; d++) { @@ -364,11 +377,15 @@ void Polygon::apply_border_forces(scalar_t dt, scalar_t xmax, scalar_t ymax) { scalar_t x = _x[v] * (1 - s) + _x[vp] * s; scalar_t y = _y[v] * (1 - s) + _y[vp] * s; scalar_t vx = 0, vy = 0; - if(x < 0) vx = x; + if(x < xmin) vx = x - xmin; else if(x > xmax) vx = x - xmax; - if(y < 0) vy = y; + if(y < ymin) vy = y - ymin; else if(y > ymax) vy = y - ymax; - apply_force(dt, x, y, - dl * vx * repulsion_constant, - dl * vy * repulsion_constant); + if(vx != 0 || vy != 0) { + // cerr << "apply_border_forces vx = " << vx << " vy = " << vy << endl; + apply_force(dt, x, y, + - dl * vx * repulsion_constant, - dl * vy * repulsion_constant); + } } } } @@ -390,9 +407,10 @@ void Polygon::apply_collision_forces(scalar_t dt, int n_polygon, Polygon *p) { distance[d] = FLT_MAX; } - // First, we tag the dots located inside the polygon p + // First, we tag the dots located inside the polygon p by looping + // through the _nb_vertices - 2 triangles from the decomposition - for(int t = 0; t < p->_nb_vertices-2; t++) { + for(int t = 0; t < p->_nb_vertices - 2; t++) { scalar_t min = 0, max = 1; scalar_t xa = p->_x[p->_triangles[t].a], ya = p->_y[p->_triangles[t].a]; scalar_t xb = p->_x[p->_triangles[t].b], yb = p->_y[p->_triangles[t].b]; @@ -514,6 +532,14 @@ void Polygon::apply_collision_forces(scalar_t dt, int n_polygon, Polygon *p) { } +bool Polygon::collide_with_borders(scalar_t xmin, scalar_t ymin, + scalar_t xmax, scalar_t ymax) { + for(int n = 0; n < _nb_vertices; n++) { + if(_x[n] <= xmin || _x[n] >= xmax || _y[n] <= ymin || _y[n] >= ymax) return true; + } + return false; +} + bool Polygon::collide(Polygon *p) { for(int n = 0; n < _nb_vertices; n++) { int np = (n+1)%_nb_vertices;