diff options
Diffstat (limited to 'src/graphicsscene.cpp')
| -rw-r--r-- | src/graphicsscene.cpp | 298 |
1 files changed, 281 insertions, 17 deletions
diff --git a/src/graphicsscene.cpp b/src/graphicsscene.cpp index e918ccc..6850c1f 100644 --- a/src/graphicsscene.cpp +++ b/src/graphicsscene.cpp @@ -12,7 +12,55 @@ namespace orphex namespace constants { const QLineF laserPlane{QPointF{-1000, 0}, QPointF{1000, 0}}; + +const auto laserColor = QColor{Qt::red}; +const auto sensorColor = QColor{Qt::red}; } + +/*! + * \brief vFoVDegrees - get "vertical" (YZ projection) Field of View (degrees) + * \param vSensorPlane - sensor plane (YZ projection) + * \param vLaserRange - laser range (YZ projection) + * \return - Field of View angle (degrees) + */ +double vFoVDegrees(const QLineF& vSensorPlane, const QLineF& vLaserRange); + +/*! + * \brief lenseBodyRect - create 2d rectangle representing lense body + * \param diameterMm - body diameter (mm) + * \param lengthMm - body length (mm) + * \return - corresponding 2d body rect + */ +QRectF lenseBodyRect(const double diameterMm, const double lengthMm); + +/*! + * \brief laserBodyRect - create 2d rectangle representing laser body + * \param diameterMm - body diameter (mm) + * \param lengthMm - body length (mm) + * \return - corresponding 2d body rect + */ +QRectF laserBodyRect(const double diameterMm, const double lengthMm); + +/*! + * \brief laserBodyRect - create 2d rectangle representing laser body + * \param diameterMm - body diameter (mm) + * \param lengthMm - body length (mm) + * \return - corresponding 2d body rect + */ + +/*! + * \brief scannerBodyFrontWallRect - create 2d rectangle representing front wall + * of scanner body + * \param thicknessMm - wall thickness (mm) + * \param offsetMm - horizontal offset from lense center (mm) + * \return - corresponding 2d body rect + */ +QRectF scannerBodyFrontWallRect( + const double thicknessMm, + const double offsetMm +); + +QList<QPointF> xzLaserAreaPolygon(const double laserAngle); } // namespace orphex GraphicsScene::GraphicsScene(QObject* parent) @@ -26,11 +74,13 @@ GraphicsScene::GraphicsScene(QObject* parent) ); m_lenseItem->setTransformOriginPoint(m_lenseItem->boundingRect().center()); - m_sensorItem = new QGraphicsLineItem(QLineF{}, m_lenseItem); - m_sensorItem->setPen(QPen{Qt::red, 0}); + m_yzSensorItem = new QGraphicsLineItem{QLineF{}, m_lenseItem}; + m_yzSensorItem->setPen(QPen{orphex::constants::sensorColor, 0}); + + m_xzSensorItem = addRect({}, QPen{orphex::constants::sensorColor, 0}); m_lineOfActionItem = new QGraphicsLineItem{ - QLineF{QPointF{0, -50}, QPointF{0, 50}}, + QLineF{QPointF{0, -1000}, QPointF{0, 1000}}, m_lenseItem }; m_lineOfActionItem->setPen(QPen{Qt::green, 0}); @@ -41,6 +91,31 @@ GraphicsScene::GraphicsScene(QObject* parent) }; m_opticalAxisItem->setPen(QPen{Qt::gray, 0}); + m_lenseVerticalPlaneItem = addLine( + QLineF{QPointF{0, -1000}, QPointF{0, 1000}}, + QPen{Qt::black, 0} + ); + + m_lenseBodyItem = addRect( + QRectF{}, + QPen{m_lenseItem->pen().color(), 0}, + QBrush{m_lenseItem->pen().color(), Qt::DiagCrossPattern} + ); + m_lenseBodyItem->setParentItem(m_lenseItem); + m_lenseBodyItem->setOpacity(0.1); + + m_laserBodyItem = addRect( + QRectF{}, + QPen{Qt::black, 0}, + QBrush{Qt::black, Qt::DiagCrossPattern} + ); + + m_scannerBodyFrontWallItem = addRect( + QRectF{}, + QPen{Qt::lightGray, 0}, + QBrush{Qt::lightGray, Qt::DiagCrossPattern} + ); + using namespace orphex::constants; m_laserPlaneItem = addLine(laserPlane, QPen{Qt::black, 0}); m_laserPlaneItem->stackBefore(m_lenseItem); @@ -55,7 +130,7 @@ GraphicsScene::GraphicsScene(QObject* parent) m_desiredImagePlaneItem = new QGraphicsLineItem(QLineF{}, m_lenseItem); m_desiredImagePlaneItem->setPen(QPen{Qt::yellow, 0.15}); - m_desiredImagePlaneItem->stackBefore(m_sensorItem); + m_desiredImagePlaneItem->stackBefore(m_yzSensorItem); m_desiredRangeAreaItem = new QGraphicsPolygonItem{m_lenseItem}; m_desiredRangeAreaItem->setPen( @@ -71,10 +146,18 @@ GraphicsScene::GraphicsScene(QObject* parent) m_actualRangeItem->setOpacity(0.5); m_actualRangeAreaItem = new QGraphicsPolygonItem{m_lenseItem}; - m_actualRangeAreaItem->setPen(QPen{m_sensorItem->pen().color(), 0}); - m_actualRangeAreaItem->setBrush(QBrush{m_sensorItem->pen().color()}); + m_actualRangeAreaItem->setPen(QPen{m_yzSensorItem->pen().color(), 0}); + m_actualRangeAreaItem->setBrush(QBrush{m_yzSensorItem->pen().color()}); m_actualRangeAreaItem->setOpacity(0.1); + m_xzActualRangeAreaItem = addPolygon( + {}, + m_actualRangeItem->pen(), + m_actualRangeAreaItem->brush() + ); + m_xzActualRangeAreaItem->setOpacity(0.1); + // m_xzActualRangeAreaItem->setParentItem(m_lenseItem); + m_sensorLenseIntersectionItem = new QGraphicsEllipseItem{ QRectF{QPointF{-1, -1}, QPointF{1, 1}}, m_lenseItem @@ -110,6 +193,23 @@ GraphicsScene::GraphicsScene(QObject* parent) lenseLaserTextItem->setDefaultTextColor( m_lenseLaserIntersectionItem->pen().color() ); + + m_xzHardwareLaserPlaneItem = addPolygon( + QPolygonF{}, + // QPen{orphex::constants::laserColor, 0.}, + QPen{Qt::black, 0.}, + // QBrush{orphex::constants::laserColor, Qt::DiagCrossPattern} + QBrush{Qt::black, Qt::DiagCrossPattern} + ); + m_xzHardwareLaserPlaneItem->setOpacity(0.2); + m_xzHardwareLaserPlaneItem->setParentItem(m_laserBodyItem); + m_xzDebugItem = addPolygon( + QPolygonF{}, + QPen{Qt::green, 0.}, + QBrush{Qt::green, Qt::DiagCrossPattern} + ); + m_xzDebugItem->setOpacity(0.1); + m_xzDebugItem->setParentItem(m_laserBodyItem); } void GraphicsScene::update(OpticalDesign* design) @@ -221,17 +321,59 @@ void GraphicsScene::update(OpticalDesign* design) const auto offset = sensorLine.pointAt(1 + offsetRatio) - sensorLine.p2(); sensorLine.setPoints(sensorLine.p1() + offset, sensorLine.p2() + offset); - m_sensorItem->setLine(sensorLine); + m_yzSensorItem->setLine(sensorLine); + + const auto sensorHalfWidth = design->get_sensorWidthMm() / 2.; + const QRectF xzSensorRect{ + QPointF{ + // m_yzSensorItem->mapToScene(sensorLine.p1()).x(), + sensorLine.p1().x(), + sensorHalfWidth + }, + QPointF{ + // m_yzSensorItem->mapToScene(sensorLine.p2()).x(), + sensorLine.p2().x(), + -sensorHalfWidth + } + }; + m_xzSensorItem->setRect(xzSensorRect); + + // const auto yzFoVAngle = QLineF{m_lenseItem->pos(), } + // const auto axisAngleD = design->get_opticalAxisAngleDegrees(); + // const QLineF sceneAxis{ + // m_opticalAxisItem->mapToScene(m_opticalAxisItem->line().p1()), + // m_opticalAxisItem->mapToScene(m_opticalAxisItem->line().p1()) + // }; + // for (auto& p : xzActualRangePolygon) + // { + // // qDebug() << "AZAZA hyp:" << p.x(); + // // p.setX(sceneAxis.x1()); + // // qt_noop(); + // // p.setX(std::sin(qDegreesToRadians(axisAngleD)) * p.x()); + // // p.setX(std::cos(qDegreesToRadians(axisAngleD)) * p.x()); + // // p.setX(p.x() / std::cos(qDegreesToRadians(axisAngleD))); + // // p.setX(m_lenseItem->mapFromScene(p).x()); + // p = QPointF + // } + + // m_xzActualRangeAreaItem->setRotation(180.); + + const auto p1 = xzSensorRect.topLeft(); + const auto p2 = xzSensorRect.bottomRight(); // find laser plane range which corresponds to sensor position m_actualRangeItem->setLine({ - imageToObject(m_sensorItem->line().p1()), - imageToObject(m_sensorItem->line().p2()), + imageToObject(m_yzSensorItem->line().p1()), + imageToObject(m_yzSensorItem->line().p2()), }); - // not that object area has negative coords + // note that object area has negative coords + // const auto tmp = m_actualRangeItem->line(); + // const auto tmp2 = m_actualRangeItem->mapToScene(tmp.p1()); + design->set_actualZBaseMm( - -m_actualRangeItem->mapToScene(m_actualRangeItem->line().p1()).x() + -m_actualRangeItem->mapToScene(m_actualRangeItem->line().p1()).x() /*+ + design->fullBodyOffset()*/ ); design->set_actualZRangeMm(m_actualRangeItem->line().length()); @@ -256,13 +398,17 @@ void GraphicsScene::update(OpticalDesign* design) // fill actual range area m_actualRangeAreaItem->setPolygon( QPolygonF{ - {m_sensorItem->line().p1(), - m_sensorItem->line().p2(), + {m_yzSensorItem->line().p1(), + m_yzSensorItem->line().p2(), m_actualRangeItem->line().p2(), m_actualRangeItem->line().p1()} } ); + design->set_vFoVDegrees( + orphex::vFoVDegrees(m_yzSensorItem->line(), m_actualRangeItem->line()) + ); + design->set_sensorLenseAngleDegrees( m_desiredImagePlaneItem->line().angleTo(m_lineOfActionItem->line()) ); @@ -273,7 +419,7 @@ void GraphicsScene::update(OpticalDesign* design) // TODO: draw lines? QPointF sensorLenseIntersection{}; - if (m_sensorItem->line().intersects( + if (m_yzSensorItem->line().intersects( m_lineOfActionItem->line(), &sensorLenseIntersection ) == QLineF::NoIntersection) @@ -317,7 +463,7 @@ void GraphicsScene::update(OpticalDesign* design) ROI |= m_actualRangeAreaItem->boundingRect(); ROI |= m_desiredRangeAreaItem->boundingRect(); ROI |= m_lenseItem->boundingRect(); - ROI |= m_sensorItem->boundingRect(); + ROI |= m_yzSensorItem->boundingRect(); ROI |= m_sensorLenseIntersectionItem->boundingRect(); ROI |= m_lenseLaserIntersectionItem->boundingRect(); @@ -332,7 +478,7 @@ void GraphicsScene::update(OpticalDesign* design) // calculate distance between sensor and lense on optical axis QPointF sensorAxisIntersection{}; - if (m_sensorItem->line().intersects( + if (m_yzSensorItem->line().intersects( m_opticalAxisItem->line(), &sensorAxisIntersection ) == QLineF::NoIntersection) @@ -425,5 +571,123 @@ void GraphicsScene::update(OpticalDesign* design) design->set_frontSharpDistanceMm(R1Mm); design->set_backSharpDistanceMm(R2Mm); - design->set_depthOfFieldMm((R2Mm - R1Mm)); + const auto depthOfFieldMm = R2Mm - R1Mm; + design->set_depthOfFieldMm(depthOfFieldMm); + + if (qFuzzyIsNull(depthOfFieldMm)) + { + emit design->depthOfFieldMmChanged(); + emit design->depthOfFieldMmChanged(depthOfFieldMm); + } + + m_lenseBodyItem->setRect( + orphex::lenseBodyRect( + design->get_lenseBodyMaxDiameterMm(), + design->get_lenseBodyLengthMm() + ) + ); + + m_laserBodyItem->setRect( + orphex::laserBodyRect( + design->get_laserBodyDiameterMm(), + design->get_laserBodyLengthMm() + ) + ); + + m_scannerBodyFrontWallItem->setRect( + orphex::scannerBodyFrontWallRect( + design->get_scannerBodyWallThicknessMm(), + design->get_scannerBodyFrontWallOffsetMm() + ) + ); + + { + m_xzHardwareLaserPlaneItem->setPolygon( + orphex::xzLaserAreaPolygon(design->get_laserAngleDegrees()) + ); + } + + { + const auto item = m_actualRangeItem; + const auto line = item->line(); + const auto x1 = item->mapToScene(line.p1()).x(); + const auto x2 = item->mapToScene(line.p2()).x(); + QPolygonF xzActualRangePolygon{QList<QPointF>{ + QPointF{x1, imageToObject(m_xzSensorItem->rect().topLeft()).y()}, + QPointF{x1, imageToObject(m_xzSensorItem->rect().bottomLeft()).y()}, + QPointF{ + x2, + imageToObject(m_xzSensorItem->rect().bottomRight()).y() + }, + QPointF{x2, imageToObject(m_xzSensorItem->rect().topRight()).y()}, + }}; + m_xzActualRangeAreaItem->setPolygon(xzActualRangePolygon); + + m_xzDebugItem->setPolygon( + QPolygonF{QList<QPointF>{ + QPointF{0., 0.}, + QPointF{ + x1, + imageToObject(m_xzSensorItem->rect().topLeft()).y() + }, + QPointF{ + x1, + imageToObject(m_xzSensorItem->rect().bottomLeft()).y() + }, + }} + ); + } +} + +double orphex::vFoVDegrees( + const QLineF& vSensorPlane, + const QLineF& vLaserRange +) +{ + const auto sl = vSensorPlane; + const auto arl = vLaserRange; + + const QLineF l0{sl.p1(), arl.p1()}; + const QLineF l1{sl.p2(), arl.p2()}; + + return l1.angleTo(l0); +} + +QRectF orphex::lenseBodyRect(const double diameterMm, const double lengthMm) +{ + return QRectF{ + QPointF{-lengthMm, -diameterMm / 2.}, + QSizeF{lengthMm, diameterMm} + }; +} + +QRectF orphex::laserBodyRect(const double diameterMm, const double lengthMm) +{ + return QRectF{QPointF{0., -diameterMm / 2.}, QSizeF{lengthMm, diameterMm}}; +} + +QRectF orphex::scannerBodyFrontWallRect( + const double thicknessMm, + const double offsetMm +) +{ + return QRectF{ + QPointF{offsetMm - thicknessMm, -1000.}, + QPointF{offsetMm, 1000.} + }; +} + +QList<QPointF> orphex::xzLaserAreaPolygon(const double laserAngle) +{ + QLineF line{QPointF{0., 0.}, QPointF{-1000., 0.}}; + + line.setAngle(180. + laserAngle / 2.); + + QList<QPointF> result{QPointF{0., 0.}, line.p2()}; + + line.setAngle(180. - laserAngle / 2.); + + result << line.p2(); + + return result; } |
