File indexing completed on 2024-04-28 15:09:53
0001 /* Ekos GuideView 0002 Child of FITSView with few additions necessary for Internal Guider 0003 0004 SPDX-FileCopyrightText: 2020 Hy Murveit <hy@murveit.com> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "guideview.h" 0010 #include "fitsviewer/fitsdata.h" 0011 0012 #include <QPainter> 0013 #include <math.h> 0014 0015 GuideView::GuideView(QWidget *parent, FITSMode mode, FITSScale filter) : FITSView(parent, mode, filter) 0016 { 0017 } 0018 0019 void GuideView::updateNeighbors() 0020 { 0021 if (newNeighbors) 0022 updateFrame(true); 0023 } 0024 0025 void GuideView::drawOverlay(QPainter *painter, double scale) 0026 { 0027 Q_UNUSED(scale); 0028 0029 FITSView::drawOverlay(painter, getScale()); 0030 0031 for (const auto &neighbor : neighbors) 0032 drawNeighbor(painter, neighbor); 0033 newNeighbors = false; 0034 0035 } 0036 0037 void GuideView::addGuideStarNeighbor(double targetX, double targetY, bool found, 0038 double detectedX, double detectedY, bool isGuideStar) 0039 { 0040 Neighbor n; 0041 n.targetX = targetX; 0042 n.targetY = targetY; 0043 n.found = found; 0044 n.detectedX = detectedX; 0045 n.detectedY = detectedY; 0046 n.isGuideStar = isGuideStar; 0047 neighbors.append(n); 0048 newNeighbors = true; 0049 } 0050 0051 void GuideView::clearNeighbors() 0052 { 0053 neighbors.clear(); 0054 } 0055 0056 // We draw a circle around each "neighbor" star and draw a line from the guide star to the neighbor 0057 // Which starts at the reticle around the guide star and ends at the circle around the neighbor. 0058 void GuideView::drawNeighbor(QPainter *painter, const Neighbor &neighbor) 0059 { 0060 double origOpacity = painter->opacity(); 0061 QPen pen(neighbor.found ? Qt::green : Qt::red); 0062 pen.setWidth(2); 0063 pen.setStyle(Qt::SolidLine); 0064 painter->setPen(pen); 0065 painter->setBrush(Qt::NoBrush); 0066 const double scale = getScale(); 0067 0068 if (!neighbor.isGuideStar) 0069 { 0070 const QPointF center(neighbor.targetX * scale, neighbor.targetY * scale); 0071 0072 double rawRadius = 10; 0073 if (imageData() != nullptr) 0074 rawRadius = std::min(20.0, std::max(3.0, imageData()->width() / 150.0)); 0075 0076 const double r = rawRadius * scale; 0077 painter->drawEllipse(center, r, r); 0078 0079 const QRect &box = getTrackingBox(); 0080 const int x1 = (box.x() + box.width() / 2.0) * scale; 0081 const int y1 = (box.y() + box.height() / 2.0) * scale; 0082 painter->setOpacity(0.25); 0083 const double dx = neighbor.targetX * scale - x1; 0084 const double dy = neighbor.targetY * scale - y1; 0085 0086 const double lineLength = std::hypotf(fabs(dx), fabs(dy)); 0087 0088 // f1 indicates the place along line between the guide star and the neighbor star 0089 // where the line should start because it intersects the reticle box around the guide star. 0090 double f1; 0091 if (std::fabs(dx) > std::fabs(dy)) 0092 { 0093 const double rBox = scale * box.width() / 2.0; 0094 f1 = std::hypot(rBox, std::fabs(dy) * rBox / std::fabs(dx)) / lineLength; 0095 } 0096 else 0097 { 0098 const double rBox = scale * box.height() / 2.0; 0099 f1 = std::hypotf(rBox, std::fabs(dx) * rBox / std::fabs(dy)) / lineLength; 0100 } 0101 // f2 indicates the place along line between the guide star and the neighbor star 0102 // where the line should stop because it intersects the circle around the neighbor. 0103 const double f2 = 1.0 - (r / lineLength); 0104 0105 if (f1 < 1 && lineLength > r) 0106 painter->drawLine(x1 + dx * f1, y1 + dy * f1, x1 + dx * f2, y1 + dy * f2); 0107 } 0108 painter->setOpacity(origOpacity); 0109 }