1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +01:00

Streamlined paint function.

This commit is contained in:
Laura Sebesta 2012-08-18 09:23:09 +02:00
parent d3daa06713
commit 375ecfb369
2 changed files with 107 additions and 78 deletions

View File

@ -50,6 +50,8 @@ namespace mapcontrol
mapfollowtype=UAVMapFollowType::None;
trailtype=UAVTrailType::ByDistance;
timer.start();
generateArrowhead();
}
UAVItem::~UAVItem()
{
@ -64,7 +66,7 @@ namespace mapcontrol
//Draw plane
painter->drawPixmap(-pic.width()/2,-pic.height()/2,pic);
//Return if context menu switch for UAV info is off
//Return if UAV Info context menu is turned off
if(!showUAVInfo){
showJustChanged=false;
return;
@ -75,46 +77,19 @@ namespace mapcontrol
//Turn on anti-aliasing so the fonts don't look terrible
painter->setRenderHint(QPainter::Antialiasing, true);
qreal arrowSize = 10;
//Set pen attributes
QColor myColor(Qt::red);
myPen.setWidth(3);
myPen.setColor(myColor);
painter->setPen(myPen);
//Create line from (0,0), to (1,1). Later, we'll scale and rotate it
QLineF line(0,0,1.0,1.0);
//Set the starting point to (0,0)
line.setP1(QPointF(0,0));
//Set angle and length
line.setLength(60.0);
line.setAngle(90.0);
//Form arrowhead
double angle = ::acos(line.dx() / line.length());
if (line.dy() <= 0)
angle = (M_PI * 2) - angle;
QPointF arrowP1 = line.pointAt(1) + QPointF(sin(angle + M_PI / 3) * arrowSize,
cos(angle + M_PI / 3) * arrowSize);
QPointF arrowP2 = line.pointAt(1) + QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize,
cos(angle + M_PI - M_PI / 3) * arrowSize);
//Generate arrowhead
arrowHead.clear();
arrowHead << line.pointAt(1) << arrowP1 << arrowP2;
painter->drawPolygon(arrowHead);
painter->setPen(myPen);
painter->drawLine(line);
painter->drawLine(arrowShaft);
//*********** Create trend arc
double radius;
double spanAngle = yawRate_dps * 5; //Forecast 5 seconds into the future
//Find the scale factor between meters and pixels
double pixels2meters = map->Projection()->GetGroundResolution(map->ZoomTotal(),coord.Lat());
float meters2pixels=1.0 / pixels2meters;
@ -164,56 +139,66 @@ namespace mapcontrol
//***** Text info overlay. The font is a "glow" font, so that it's easier to use on the map
if (refreshPaint_flag==true){
//Define font
QFont borderfont( "Arial", 14, QFont::Normal, false );
//Top left corner of text
int textAnchorX = 20;
int textAnchorY = 20;
//Create text lines
QString uavoInfoStrLine1, uavoInfoStrLine2;
QString uavoInfoStrLine3, uavoInfoStrLine4;
QString uavoInfoStrLine5;
//For whatever reason, Qt does not let QPainterPath have text wrapping. So each line of
//text has to be added to a different line.
uavoInfoStrLine1.append(QString("CAS: %1 kph").arg(CAS_mps));
uavoInfoStrLine2.append(QString("Groundspeed: %1 kph").arg(groundspeed_kph, 0, 'f',1));
uavoInfoStrLine3.append(QString("Lat-Lon: %1, %2").arg(coord.Lat(), 0, 'f',7).arg(coord.Lng(), 0, 'f',7));
uavoInfoStrLine4.append(QString("North-East: %1 m, %2 m").arg(NED[0], 0, 'f',1).arg(NED[1], 0, 'f',1));
uavoInfoStrLine5.append(QString("Altitude: %1 m").arg(-NED[2], 0, 'f',1));
//Add the uavo info text to the path
//NOTE: We must use QPainterPath for the outlined text font. QPaint does not support this.
path = QPainterPath();
path.addText(textAnchorX, textAnchorY+16*0, borderfont, uavoInfoStrLine1);
path.addText(textAnchorX, textAnchorY+16*1, borderfont, uavoInfoStrLine2);
path.addText(textAnchorX, textAnchorY+16*2, borderfont, uavoInfoStrLine3);
path.addText(textAnchorX, textAnchorY+16*3, borderfont, uavoInfoStrLine4);
path.addText(textAnchorX, textAnchorY+16*4, borderfont, uavoInfoStrLine5);
//Add text for time rings.
if(groundspeed_mps > 0){
//Always add the left side...
path.addText(-(groundspeed_mps_filt*ringTime*1*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime,0,'f',0));
path.addText(-(groundspeed_mps_filt*ringTime*2*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime*2,0,'f',0));
path.addText(-(groundspeed_mps_filt*ringTime*4*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime*4,0,'f',0));
//... and add the right side, only if it doesn't interfere with the uav info text
if(groundspeed_mps_filt*ringTime*4*meters2pixels > 200){
if(groundspeed_mps_filt*ringTime*2*meters2pixels > 200){
if(groundspeed_mps_filt*ringTime*1*meters2pixels > 200){
path.addText(groundspeed_mps_filt*ringTime*1*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime,0,'f',0));
}
path.addText(groundspeed_mps_filt*ringTime*2*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime*2,0,'f',0));
}
path.addText(groundspeed_mps_filt*ringTime*4*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime*4,0,'f',0));
}
}
//Last thing to do: set bound rectangle as function of largest object
boundingRectSize=groundspeed_mps_filt*ringTime*4*meters2pixels+20; //Largest object is currently the biggest ring + a little bit of margin for the text
refreshPaint_flag=false;
}
//Rotate the text back to vertical
qreal rot=this->rotation();
painter->rotate(-1*rot);
//Define font
QFont borderfont( "Arial", 14, QFont::Normal, false );
//Top left corner of text
int textAnchorX = 20;
int textAnchorY = 20;
//Create text lines
QString uavoInfoStrLine1, uavoInfoStrLine2;
QString uavoInfoStrLine3, uavoInfoStrLine4;
QString uavoInfoStrLine5;
//For whatever reason, Qt does not let QPainterPath have text wrapping. So each line of
//text has to be added to a different line.
uavoInfoStrLine1.append(QString("CAS: %1 kph").arg(CAS_mps));
uavoInfoStrLine2.append(QString("Groundspeed: %1 kph").arg(groundspeed_kph, 0, 'f',1));
uavoInfoStrLine3.append(QString("Lat-Lon: %1, %2").arg(coord.Lat(), 0, 'f',7).arg(coord.Lng(), 0, 'f',7));
uavoInfoStrLine4.append(QString("North-East: %1 m, %2 m").arg(NED[0], 0, 'f',1).arg(NED[1], 0, 'f',1));
uavoInfoStrLine5.append(QString("Altitude: %1 m").arg(-NED[2], 0, 'f',1));
//Add the uavo info text to the path
//NOTE: We must use QPainterPath for the outlined text font. QPaint does not support this.
QPainterPath path;
path.addText(textAnchorX, textAnchorY+16*0, borderfont, uavoInfoStrLine1);
path.addText(textAnchorX, textAnchorY+16*1, borderfont, uavoInfoStrLine2);
path.addText(textAnchorX, textAnchorY+16*2, borderfont, uavoInfoStrLine3);
path.addText(textAnchorX, textAnchorY+16*3, borderfont, uavoInfoStrLine4);
path.addText(textAnchorX, textAnchorY+16*4, borderfont, uavoInfoStrLine5);
//Add text for time rings.
if(groundspeed_mps > 0){
//Always add the left side...
path.addText(-(groundspeed_mps_filt*ringTime*1*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime,0,'f',0));
path.addText(-(groundspeed_mps_filt*ringTime*2*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime*2,0,'f',0));
path.addText(-(groundspeed_mps_filt*ringTime*4*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime*4,0,'f',0));
//... and add the right side, only if it doesn't interfere with the uav info text
if(groundspeed_mps_filt*ringTime*4*meters2pixels > 200){
if(groundspeed_mps_filt*ringTime*2*meters2pixels > 200){
if(groundspeed_mps_filt*ringTime*1*meters2pixels > 200){
path.addText(groundspeed_mps_filt*ringTime*1*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime,0,'f',0));
}
path.addText(groundspeed_mps_filt*ringTime*2*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime*2,0,'f',0));
}
path.addText(groundspeed_mps_filt*ringTime*4*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime*4,0,'f',0));
}
}
//Now draw the text. First pass is the outline...
myPen.setWidth(4);
@ -229,9 +214,6 @@ namespace mapcontrol
painter->setPen(myPen);
painter->drawPath(path);
//Last thing to do: set bound rectangle as function of largest object
boundingRectSize=groundspeed_mps_filt*ringTime*4*meters2pixels+20; //Largest object is currently the biggest ring + a little bit of margin for the text
}
QRectF UAVItem::boundingRect()const
@ -254,6 +236,8 @@ namespace mapcontrol
this->NED[0] = NED[0];
this->NED[1] = NED[1];
this->NED[2] = NED[2];
refreshPaint_flag=true;
}
void UAVItem::SetYawRate(double yawRate_dps){
@ -266,10 +250,13 @@ namespace mapcontrol
this->yawRate_dps=5e-1;
}
refreshPaint_flag=true;
}
void UAVItem::SetCAS(double CAS_mps){
this->CAS_mps=CAS_mps;
refreshPaint_flag=true;
}
void UAVItem::SetGroundspeed(double vNED[3], int m_maxUpdateRate_ms){
@ -371,6 +358,8 @@ namespace mapcontrol
}
}
refreshPaint_flag=true;
}
/**
@ -387,6 +376,8 @@ namespace mapcontrol
if (this->rotation() != value)
this->setRotation(value);
}
refreshPaint_flag=true;
}
@ -413,7 +404,9 @@ namespace mapcontrol
ww->setLine(map->FromLatLngToLocal(ww->coord1).X(),map->FromLatLngToLocal(ww->coord1).Y(),map->FromLatLngToLocal(ww->coord2).X(),map->FromLatLngToLocal(ww->coord2).Y());
}
refreshPaint_flag=true;
}
void UAVItem::SetTrailType(const UAVTrailType::Types &value)
{
trailtype=value;
@ -455,4 +448,32 @@ namespace mapcontrol
update();
}
void UAVItem::generateArrowhead(){
qreal arrowSize = 10;
//Create line from (0,0), to (1,1). Later, we'll scale and rotate it
arrowShaft=QLineF(0,0,1.0,1.0);
//Set the starting point to (0,0)
arrowShaft.setP1(QPointF(0,0));
//Set angle and length
arrowShaft.setLength(60.0);
arrowShaft.setAngle(90.0);
//Form arrowhead
double angle = ::acos(arrowShaft.dx() / arrowShaft.length());
if (arrowShaft.dy() <= 0)
angle = (M_PI * 2) - angle;
QPointF arrowP1 = arrowShaft.pointAt(1) + QPointF(sin(angle + M_PI / 3) * arrowSize,
cos(angle + M_PI / 3) * arrowSize);
QPointF arrowP2 = arrowShaft.pointAt(1) + QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize,
cos(angle + M_PI - M_PI / 3) * arrowSize);
//Assemble arrowhead
arrowHead.clear();
arrowHead << arrowShaft.pointAt(1) << arrowP1 << arrowP2;
}
}

View File

@ -221,8 +221,11 @@ namespace mapcontrol
void SetShowUAVInfo(bool const& value);
private:
void generateArrowhead();
MapGraphicItem* map;
QPolygonF arrowHead;
QLineF arrowShaft;
int altitude;
UAVMapFollowType::Types mapfollowtype;
UAVTrailType::Types trailtype;
@ -252,6 +255,11 @@ namespace mapcontrol
float boundingRectSize;
bool showJustChanged;
bool refreshPaint_flag;
QPainterPath path;
public slots:
signals: