1 #include "ControlPointGraphicsItem.h" 8 #include <QGraphicsScene> 9 #include <QGraphicsSceneContextMenuEvent> 11 #include <QMessageBox> 13 #include <QPainterPath> 21 #include "MosaicGraphicsView.h" 22 #include "MosaicSceneWidget.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>]";
const double Null
Value for an Isis Null pixel.
A Constrained point is a Control Point whose lat/lon/radius is somewhat established and should not be...
A Fixed point is a Control Point whose lat/lon is well established and should not be changed...
const double PI
The mathematical constant PI.
bool m_colorByMeasureCount
Are we coloring the movement arrow based on CP measure count.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube's serial number.
double GetResidualMagnitude() const
Return Residual magnitude.
Namespace for the standard library.
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *widget=0)
This virtual paint method is called anytime an update() or paintEvent() is called.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
QString editPointId()
Return the current control point id loaded in the ControlPointEditWidget.
double Maximum() const
Returns the absolute maximum double found in all data passed through the AddData method.
This class is used to accumulate statistics on double arrays.
double m_residualMagnitude
Residual magnitude threshold for colored vs. black.
QString GetId() const
Return the Id of the control point.
QList< QString > getCubeSerialNumbers() const
QList< ControlMeasure *> getMeasures(bool excludeIgnored=false) const
bool IsSpecial(const double d)
Returns if the input pixel is special.
QString GetPointTypeString() const
Obtain a string representation of the PointType.
Namespace for ISIS/Bullet specific routines.
int m_measureCount
Measure count threshold for colored vs. black.
PointType GetType() const
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
Serial Number list generator.
double Average() const
Computes and returns the average.
bool m_colorByResidualMagnitude
Are we coloring the movement arrow based on max CM residual magnitude.