chassiscircular2.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by David Saxton                                    *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "chassiscircular2.h"
00012 
00013 #include "libraryitem.h"
00014 
00015 #include <klocale.h>
00016 #include <qpainter.h>
00017 #include <qwmatrix.h>
00018 
00019 #include <algorithm>
00020 #include <cmath>
00021 
00022 double normalizeAngle( double angle );
00023 
00024 
00025 Item* ChassisCircular2::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00026 {
00027         return new ChassisCircular2( (MechanicsDocument*)itemDocument, newItem, id );
00028 }
00029 
00030 
00031 LibraryItem* ChassisCircular2::libraryItem()
00032 {
00033         return new LibraryItem(
00034                 QString("mech/chassis_circular_2"),
00035                 i18n("Circular 2-Wheel Chassis"),
00036                 i18n("Chassis'"),
00037                 "chassis.png",
00038                 LibraryItem::lit_mechanical,
00039                 ChassisCircular2::construct );
00040 }
00041 
00042 
00043 ChassisCircular2::ChassisCircular2( MechanicsDocument *mechanicsDocument, bool newItem, const char *id )
00044         : MechanicsItem( mechanicsDocument, newItem, (id) ? id : "chassis_circular_2" )
00045 {
00046         m_name = i18n("Circular 2-Wheel Chassis");
00047         m_desc = i18n("A circular base with two wheels and a support point.");
00048         
00049         m_theta1 = 0.0;
00050         m_theta2 = 0.0;
00051         
00052         QPointArray pa;
00053         pa.makeEllipse( -25, -25, 50, 50 );
00054         QWMatrix m(4,0,0,4,0,0);
00055         m.setTransformationMode( QWMatrix::Areas );
00056         pa = m.map(pa);
00057         setItemPoints(pa);
00058         
00059         itemResized();
00060 }
00061 
00062 
00063 ChassisCircular2::~ChassisCircular2()
00064 {
00065 }
00066 
00067 
00068 void ChassisCircular2::itemResized()
00069 {
00070         const double w = sizeRect().width();
00071         const double h = sizeRect().height();
00072         
00073         m_wheel1Pos = QRect( int(w/5), int(h/6), int(w/4), int(h/8) );
00074         m_wheel2Pos = QRect( int(w/5), int(5*h/6-h/8), int(w/4), int(h/8) );
00075 }
00076 
00077 
00078 void ChassisCircular2::advance( int phase )
00079 {
00080         if ( phase != 1 )
00081                 return;
00082         
00083         double speed1 = 60.; // pixels per second
00084         double speed2 = 160.; // pixels per second
00085         
00086         m_theta1 = normalizeAngle( m_theta1 + (speed1/1000.)/m_wheel1Pos.width() );
00087         m_theta2 = normalizeAngle( m_theta2 + (speed2/1000.)/m_wheel2Pos.width() );
00088         
00089         const double d1 = speed1/1000.;
00090         const double d2 = speed2/1000.;
00091         const double sep = m_wheel2Pos.center().y()-m_wheel1Pos.center().y();
00092         
00093         double dtheta = std::atan( (d2-d1)/sep ); // Change in orientation of chassis
00094         double moveAngle = absolutePosition().angle()+dtheta/2;
00095         rotateBy(dtheta);
00096         moveBy( ((d1+d2)/2.)*std::cos(moveAngle), ((d1+d2)/2.)*std::sin(moveAngle) );
00097 }
00098 
00099 
00100 void ChassisCircular2::drawShape( QPainter &p )
00101 {
00102         const double _x = int(sizeRect().x() + x());
00103         const double _y = int(sizeRect().y() + y());
00104         const double w = sizeRect().width();
00105         const double h = sizeRect().height(); 
00106         
00107         initPainter(p);
00108         p.setBrush( QColor( 255, 246, 210 ) );
00109         QRect circleRect = sizeRect();
00110         circleRect.moveLeft( int(circleRect.left() + x()) );
00111         circleRect.moveTop( int(circleRect.top() + y()) );
00112         p.drawEllipse(circleRect);
00113         
00114         // Draw wheels
00115         // TODO get this info from m_wheel1Pos and m_wheel2Pos
00116         const double X = _x+(w/5); // Wheel's left pos
00117         const double H = h/8; // Wheel's height
00118         const double y1 = _y+(h/6); // Wheel 1 y-pos
00119         const double y2 = _y+(5*h/6)-H; // Wheel 2 y-pos
00120         
00121         p.setPen( Qt::NoPen );
00122         const double stripeWidth = 5;
00123         const double offset2 = 1 + int(m_theta1*m_wheel1Pos.width())%int(2*stripeWidth);
00124         const double offset1 = 1 + int(m_theta2*m_wheel2Pos.width())%int(2*stripeWidth);
00125         p.setBrush( QColor( 255, 232, 182 ) );
00126         for ( double i=-1; i<std::ceil(m_wheel1Pos.width()/stripeWidth); ++i )
00127         {
00128                 
00129                 p.setClipRect( QRect( int(_x+m_wheel1Pos.x()+2), int(_y+m_wheel1Pos.y()+2), int(m_wheel1Pos.width()-4), int(m_wheel1Pos.height()-4) ), QPainter::CoordPainter );
00130                 p.drawRect( int(offset1+X + i*stripeWidth*2), int(y1+1), int(stripeWidth), int(H-2) );
00131                 
00132                 p.setClipRect( QRect( int(_x+m_wheel2Pos.x()+2), int(_y+m_wheel2Pos.y()+2), int(m_wheel2Pos.width()-4), int(m_wheel2Pos.height()-4) ), QPainter::CoordPainter );
00133                 p.drawRect( int(offset2+X + i*stripeWidth*2), int(y2+1), int(stripeWidth), int(H-2) );
00134         }
00135         p.setClipping(false);
00136         
00137         p.setPen( Qt::black );
00138         p.setBrush( Qt::NoBrush );
00139         p.drawRoundRect( int(X), int(y1), int(w/4), int(H), 25, 50 );
00140         p.drawRoundRect( int(X), int(y2), int(w/4), int(H), 25, 50 );
00141         
00142         
00143         deinitPainter(p);
00144 }

Generated on Tue May 8 17:05:28 2007 for KTechLab by  doxygen 1.5.1