wojtekwjk Temat założony przez niniejszego użytkownika |
Wskaźnik analogowy,prymitywy-płynny ruch strzałki » 2015-06-07 00:48:18 Witam; Od pewnego czasu zajmuje się programowaniem w Rad studio XE7.Muszę zrobić miernik analogowy z ruchomą strzałką przy pomocy prymitywów.80% projektu jest już gotowe,problem polega na tym że nie wiem jak zrobić płynny efekt poruszania się strzałki.Szukałem dość długo w internecie,ale niestety nie udało mi się znaleźć nic co by mi pomogło.W moim przypadku strzałka przeskakuje od położenia 0 do oczekiwanej wartości.Próby wciśnięcia kodu na linie o kolorze RGB (250,250,250,) powodowały powstawanie dziwnych figur na polu miernika.Poniżej zamieszczam fragment kodu.Domyślam sie że problem polega na umieszczeniu narzędzie rysujacego w odpowiednim miejscu pętli.Wskazówka porusza się na podstawie wpisanego przez użytkownika wyniku oraz współrzędnych które są na jego podstawie wyliczane.Im większy wynik tym x oraz y większe i pętla rysuje dłużej. Będe bardzo wdzięczny za jakąkolwiek pomoc,gdyż póki co niestety utknąłem w miejscu. Pozdrawiam.
if (wynik <50 ) { b=102-wynik ; a=16+2*wynik; for (x= 16; x <=a; x++) { WskazowkaBiał() ; //zerowanie wskazówki w war 0 for (y = 102; y >=b; y--) { }
} Tarcza->Canvas->Pen->Width= 2; Tarcza->Canvas->Pen->Color=RGB(253,0,3); Tarcza->Canvas->MoveTo(180,295); Tarcza->Canvas->LineTo(x,y); Image1->Canvas->CopyRect(ProstTarcza,Tarcza->Canvas,ProstTarcza); } |
|
Monika90 |
» 2015-06-07 11:10:48 Jeżeli chcesz mieć animację to użyj timera. To XE7 chyba ma coś takiego jak TTimer. |
|
Monika90 |
» 2015-06-07 12:49:54 A tak można to zrobić w SFML (oczywiście wiem że ten kod Ci w niczym nie pomoże, ale chciałam pokazać innym :) ) #include <SFML/Window.hpp> #include <SFML/Graphics.hpp> #include <random>
template < class Animation > void run( Animation & anim ) { sf::ContextSettings settings; settings.antialiasingLevel = 8; sf::RenderWindow wnd( sf::VideoMode( 640, 480 ), anim.name(), sf::Style::Default, settings ); wnd.setVerticalSyncEnabled( true ); while( wnd.isOpen() ) { sf::Event ev; while( wnd.pollEvent( ev ) ) { switch( ev.type ) { case sf::Event::Closed: wnd.close(); return; case sf::Event::KeyPressed: anim.key_down( ev.key.code ); break; } } anim.paint( wnd ); anim.frame(); wnd.display(); } }
constexpr double pi = 3.1415926535897932384626433832795;
class Lowpass4Pole { public: explicit Lowpass4Pole( double cutoff, double q = 1 ) { k_ = 1; double b1 = 0.76536686473017954 / q / cutoff; const double b2 = 1 /( cutoff * cutoff ); bilinear_lp( b1, b2, b1_1_, b2_1_, k_ ); b1 = 1.8477590650225735 / cutoff; bilinear_lp( b1, b2, b1_2_, b2_2_, k_ ); } double operator ()( double x ) { x *= k_; const double t1 = x - h1_1_ * b1_1_ - h2_1_ * b2_1_; const double y1 = t1 + 2 * h1_1_ + h2_1_; h2_1_ = h1_1_; h1_1_ = t1; const double t2 = y1 - h1_2_ * b1_2_ - h2_2_ * b2_2_; const double y2 = t2 + 2 * h1_2_ + h2_2_; h2_2_ = h1_2_; h1_2_ = t2; return y2; } private: static void bilinear_lp( double b1, double b2, double & out_b1, double & out_b2, double & k ) { const double bd = 4 * b2 + 2 * b1 + 1; k /= bd; out_b1 =( 2 - 8 * b2 ) / bd; out_b2 =( 4 * b2 - 2 * b1 + 1 ) / bd; } double k_, b1_1_, b2_1_, b1_2_, b2_2_; double h1_1_ = 0, h2_1_ = 0, h1_2_ = 0, h2_2_ = 0; };
class Meter { public: explicit Meter( float x, float y, float radius ) { plate_.setPointCount( 64 ); plate_.setRadius( radius + 10 ); plate_.setOrigin( plate_.getRadius(), plate_.getRadius() ); plate_.setPosition( x, y ); plate_.setFillColor( { 0, 0, 0 } ); hand_.setPointCount( 3 ); hand_.setPoint( 0, { 0, - radius } ); hand_.setPoint( 1, { - 5, 0 } ); hand_.setPoint( 2, { 5, 0 } ); hand_.setPosition( x, y ); hand_.setFillColor( { 255, 0, 0 } ); } void set( float target ) { target_ = target; } void paint( sf::RenderTarget & r ) const { r.draw( plate_ ); r.draw( hand_ ); } void frame() { hand_.setRotation( filter_( target_ ) * 45 ); } private: float target_ = 0; sf::ConvexShape hand_; sf::CircleShape plate_; Lowpass4Pole filter_ { 0.126, 1.1 }; };
class Demo { public: static auto name() { return "Analog Meter"; } void paint( sf::RenderTarget & r ) const { r.clear( sf::Color( 100, 180, 255 ) ); meter_.paint( r ); } void frame() { meter_.frame(); } void key_down( int code ) { if( code == sf::Keyboard::Space ) meter_.set( dist_( rnd_ ) ); } private: Meter meter_ { 320, 240, 120 }; std::mt19937 rnd_; std::uniform_real_distribution < float > dist_ { - 1, 1 }; };
int main() { Demo d; run( d ); }
Program wyświetla czerwoną wskazówkę, naciśnięcie spacji powoduje przestawienie jej na losową pozycję. Wskazówka ma bezwładność. |
|
« 1 » |