From: Erik K. <kru...@uq...> - 2003-01-10 14:44:12
|
kruus@kruus:/borg/local/src/arianne-cvs/arianne/src$ grep -r '\<round\>' * 2dclient/src/KAObject.cpp: ActionNumber = round((double)NumActions * fmod(o, M_2PI) / (M_2PI)) % NumActions; 2dclient/src/KAObject.cpp: //ActionNumber = round((double)NumActions * orientation / 360) % NumActions; 2dclient/src/KAObject.cpp: ActionNumber = round((double)NumActions * fmod(o, M_2PI) / (M_2PI)) % NumActions; 3dclient/src/Terrain.cpp: Blocks[round((x+20)/10)][round((y+30)/10)] = type; common/basic/Conversion/Conversion.h:inline int round(double value) newcommon/basic/Conversion/Conversion.h:inline int round(double value) 1) ActionNumber = round((double)NumActions * fmod(o, M_2PI) / (M_2PI)) % NumActions does *not* calculate circularly varying numbers from 0..NumActions-1 even if round were to round to a closest integer. Think of sign of 'fmod' and sign of 'a%b' for -a 2) arianne's round function is not only complicated, inline int arianne_round(double value) { return (int) (value - ((int) value) < 0.5 ? floor(value) : ceil(value)); } but it does not round integers to nearest integers. Think of (int)(-1.23) if confused. Anyway this borken math is in 2dclient mostly, which is absent from configure.in at the moment... is this code even worth fixing? What cvs dirs can safely be treated as 'obsolete' at this point? and which can be considered as worthwhile fixing, even if not yet part of the new scheme of things? Erik. ---------------------------------- Quick test program if you didn't spot what the code was really calculating: #include <cmath> #include <iostream> #include <iomanip> #include <cmath> #define M_2PI (M_PI*2.0) #define M_2PI_INV (M_1_PI*0.5) // rounds fine for +ve numbers, but is weird for -ve numbers inline int arianne_round(double value) { return (int) (value - ((int) value) < 0.5 ? floor(value) : ceil(value)); } // always rounds to a nearest integer, rounding halfways upward. inline int alt_round(double value) { return (int) floor(value+0.5); // halfways up, like arianne_round on +ves //return (int) ceil(value-0.5); // rounds halfways down } // returns a number between zero and N-1, as value varies cyclically // betweern [0,max]. (or returns 0 for invalid inputs) inline int circ_mod(double value, double max_inv, int N) { if(max_inv<=0.0 || N<=1) return 0; double x=value*max_inv; return (int)((x-floor(x))*N); // NB: x-floor(x) is guarenteed to be in [0,1) } int main(int,char**) { for (double x=(-2.0); x<=2.0; x+=0.25){ std::cout<<"arianne_round("<<std::setw(10)<<x<<") = " <<setw(4)<<arianne_round(x) <<" (alt_round="<<alt_round(x)<<')'<<std::endl; } // presumably you want a sprite number or something that varies // cyclically with orientation `o'... between 0 and NumActions-1. const int NumActions=4; for(double o=(-M_2PI); o<=1.5*M_2PI; o+=0.125*M_2PI){ std::cout<<"o="<<std::setw(10)<<o <<" arianne: "<<std::setw(10) <<arianne_round((double)NumActions * fmod(o, M_2PI) / (M_2PI)) % NumActions <<" circ_mod: "<<std::setw(10) <<circ_mod(o, M_2PI_INV, NumActions) <<std::endl; } } |