00001
00002
00003
00004
00005
00006
00007
00008
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.;
00084 double speed2 = 160.;
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 );
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
00115
00116 const double X = _x+(w/5);
00117 const double H = h/8;
00118 const double y1 = _y+(h/6);
00119 const double y2 = _y+(5*h/6)-H;
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 }