1 #include "ControlPointGraphicsItem.h"
8 #include <QGraphicsScene>
9 #include <QGraphicsSceneContextMenuEvent>
11 #include <QMessageBox>
13 #include <QPainterPath>
16 #include "Constants.h"
17 #include "ControlMeasure.h"
18 #include "ControlPoint.h"
19 #include "Directory.h"
21 #include "MosaicGraphicsView.h"
22 #include "MosaicSceneWidget.h"
23 #include "SerialNumberList.h"
24 #include "Statistics.h"
33 ControlPointGraphicsItem::ControlPointGraphicsItem(QPointF center,
37 m_centerPoint =
new QPointF(center);
38 m_mosaicScene = boundingRectSrc;
49 m_origPoint =
new QPointF(apriori);
52 if (cp->IsIgnored()) {
53 setPen(QPen(Qt::yellow, 0.0));
57 setPen(QPen(Qt::magenta, 0.0));
60 setPen(QPen(Qt::darkGreen, 0.0));
63 setBrush(Qt::NoBrush);
65 setToolTip(makeToolTip(snList));
69 setFlag(QGraphicsItem::ItemIsSelectable,
true);
70 setFlag(QGraphicsItem::ItemIsFocusable,
true);
77 ControlPointGraphicsItem::~ControlPointGraphicsItem() {
100 const QStyleOptionGraphicsItem *style,
QWidget * widget) {
102 QRectF fullRect = calcRect();
103 QRectF crosshairRect = calcCrosshairRect();
105 if (crosshairRect.isNull()) {
109 if (rect() != fullRect) {
113 painter->setPen(pen());
114 painter->setBrush(brush());
116 QPointF center = crosshairRect.center();
118 QPointF centerLeft(crosshairRect.left(), center.y());
119 QPointF centerRight(crosshairRect.right(), center.y());
120 QPointF centerTop(center.x(), crosshairRect.top());
121 QPointF centerBottom(center.x(), crosshairRect.bottom());
123 if (m_mosaicScene->directory() &&
127 path.addEllipse(crosshairRect);
128 path.moveTo(centerTop);
129 path.lineTo(centerBottom);
130 path.moveTo(centerLeft);
131 path.lineTo(centerRight);
133 painter->setPen(QPen(Qt::red, 0.0));
134 painter->drawPath(path);
137 painter->drawLine(centerLeft, centerRight);
138 painter->drawLine(centerTop, centerBottom);
141 if (!m_origPoint->isNull() && *m_origPoint != *m_centerPoint
145 painter->setPen(Qt::black);
146 painter->setBrush(Qt::black);
149 QColor zeroColor(Qt::black);
150 QColor fullColor(Qt::green);
152 bool isColored =
false;
156 int measureCount = m_controlPoint->
getMeasures(
true).count();
157 isColored = (measureCount >= fullColorMeasureCount);
160 fullColor = QColor(Qt::red);
162 double fullColorErrorMag = 0.0;
174 double errorMag = residualStats.
Maximum();
175 if (errorMag >= fullColorErrorMag) {
181 QColor finalColor = isColored? fullColor : zeroColor;
183 painter->setPen(finalColor);
184 painter->setBrush(finalColor);
186 painter->drawLine(*m_origPoint, *m_centerPoint);
188 QPolygonF arrowHead = calcArrowHead();
189 painter->drawPolygon(arrowHead);
195 ControlPoint *ControlPointGraphicsItem::controlPoint() {
196 return m_controlPoint;
199 void ControlPointGraphicsItem::setArrowVisible(
bool visible,
200 bool colorByMeasureCount,
202 bool colorByResidualMagnitude,
203 double residualMagnitude) {
204 m_showArrow = visible;
214 void ControlPointGraphicsItem::contextMenuEvent(
215 QGraphicsSceneContextMenuEvent * event) {
218 QAction *title = menu.addAction(
219 m_controlPoint->
GetId());
220 title->setEnabled(
false);
223 QAction *infoAction = menu.addAction(
"Show Point Info");
225 QAction *selected = menu.exec(event->screenPos());
227 if (selected == infoAction) {
228 QMessageBox::information(m_mosaicScene,
"Control Point Information",
234 QRectF ControlPointGraphicsItem::calcRect()
const {
235 QRectF pointRect(calcCrosshairRect());
237 if (!m_origPoint->isNull() && pointRect.isValid()) {
239 if (pointRect.left() > m_origPoint->x()) {
240 pointRect.setLeft(m_origPoint->x());
242 else if (pointRect.right() < m_origPoint->x()) {
243 pointRect.setRight(m_origPoint->x());
246 if (pointRect.top() > m_origPoint->y()) {
247 pointRect.setTop(m_origPoint->y());
249 else if (pointRect.bottom() < m_origPoint->y()) {
250 pointRect.setBottom(m_origPoint->y());
254 QPolygonF arrowHead = calcArrowHead();
256 if (arrowHead.size() > 2) {
257 pointRect = pointRect.united(arrowHead.boundingRect());
264 QRectF ControlPointGraphicsItem::calcCrosshairRect()
const {
267 if (m_centerPoint && !m_centerPoint->isNull() && m_mosaicScene) {
268 static const int size = 12;
269 QPoint findSpotScreen =
270 m_mosaicScene->getView()->mapFromScene(*m_centerPoint);
271 QPoint findSpotTopLeftScreen =
272 findSpotScreen - QPoint(size / 2, size / 2);
274 QRect pointRectScreen(findSpotTopLeftScreen, QSize(size, size));
277 m_mosaicScene->getView()->mapToScene(pointRectScreen).boundingRect();
284 QPolygonF ControlPointGraphicsItem::calcArrowHead()
const {
287 if (m_showArrow && !m_origPoint->isNull() &&
288 *m_origPoint != *m_centerPoint) {
289 QRectF crosshairRect = calcCrosshairRect();
290 double headSize = crosshairRect.width() * 4.0 / 5.0;
292 double crosshairSize = headSize;
295 QPointF lineVector = *m_centerPoint - *m_origPoint;
296 double lineVectorMag = sqrt(lineVector.x() * lineVector.x() +
297 lineVector.y() * lineVector.y());
298 double thetaPointOnLine = crosshairSize / (2 * (tanf(
PI / 6) / 2) *
300 QPointF pointOnLine = *m_centerPoint - thetaPointOnLine * lineVector;
302 QPointF normalVector = QPointF(-lineVector.y(), lineVector.x());
303 double thetaNormal = crosshairSize / (2 * lineVectorMag);
305 QPointF leftPoint = pointOnLine + thetaNormal * normalVector;
306 QPointF rightPoint = pointOnLine - thetaNormal * normalVector;
308 arrowHead << leftPoint << crosshairRect.center() << rightPoint;
315 QString ControlPointGraphicsItem::makeToolTip(SerialNumberList *snList) {
316 QString toolTip =
"<div>Point ID: " +
317 m_controlPoint->
GetId();
318 toolTip +=
"<br />Point Type: " +
320 toolTip +=
"<br />Number of Measures: ";
321 toolTip +=
toString(m_controlPoint->GetNumMeasures());
322 toolTip +=
"<br />Ignored: ";
323 toolTip += m_controlPoint->IsIgnored() ?
"Yes" :
"No";
324 toolTip +=
"<br />Edit Locked: ";
325 toolTip += m_controlPoint->IsEditLocked() ?
"Yes" :
"No";
329 if (snList == NULL) {
335 for(
int snIndex = 0; snIndex < serialNums.size(); snIndex ++) {
336 QString serialNum = serialNums[snIndex];
342 if (snList->hasSerialNumber(serialNum)) {
344 FileName(snList->fileName(serialNum)).name();
345 toolTip +=
" (" + serialNum +
")";
348 toolTip += serialNum;
352 if (residMag !=
Null) {
353 toolTip +=
" [residual: <font color='red'>" +
toString(residMag) +
"</font>]";