summaryrefslogtreecommitdiff
path: root/src/graphicsscene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphicsscene.cpp')
-rw-r--r--src/graphicsscene.cpp298
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;
}