summaryrefslogtreecommitdiff
path: root/src/graphicsscene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphicsscene.cpp')
-rw-r--r--src/graphicsscene.cpp199
1 files changed, 198 insertions, 1 deletions
diff --git a/src/graphicsscene.cpp b/src/graphicsscene.cpp
index 52416d5..e918ccc 100644
--- a/src/graphicsscene.cpp
+++ b/src/graphicsscene.cpp
@@ -4,6 +4,8 @@
#include <QGraphicsEllipseItem>
#include <QGraphicsLineItem>
#include <QGraphicsPolygonItem>
+#include <QGraphicsTextItem>
+#include <QGraphicsView>
namespace orphex
{
@@ -31,7 +33,7 @@ GraphicsScene::GraphicsScene(QObject* parent)
QLineF{QPointF{0, -50}, QPointF{0, 50}},
m_lenseItem
};
- m_lineOfActionItem->setPen(QPen{Qt::gray, 0});
+ m_lineOfActionItem->setPen(QPen{Qt::green, 0});
m_opticalAxisItem = new QGraphicsLineItem{
QLineF{QPointF{-1000, 0}, QPointF{1000, 0}},
@@ -72,10 +74,47 @@ GraphicsScene::GraphicsScene(QObject* parent)
m_actualRangeAreaItem->setPen(QPen{m_sensorItem->pen().color(), 0});
m_actualRangeAreaItem->setBrush(QBrush{m_sensorItem->pen().color()});
m_actualRangeAreaItem->setOpacity(0.1);
+
+ m_sensorLenseIntersectionItem = new QGraphicsEllipseItem{
+ QRectF{QPointF{-1, -1}, QPointF{1, 1}},
+ m_lenseItem
+ };
+ m_sensorLenseIntersectionItem->setPen(QPen{Qt::red, 0.1});
+
+ const auto sensorLenseTextItem = new QGraphicsTextItem{
+ tr("Scheimpflug: sensor/lense"),
+ m_sensorLenseIntersectionItem
+ };
+
+ sensorLenseTextItem->setPos(QPointF{-6, -8});
+ auto font = sensorLenseTextItem->font();
+ font.setPixelSize(2);
+ sensorLenseTextItem->setFont(font);
+ sensorLenseTextItem->setDefaultTextColor(
+ m_sensorLenseIntersectionItem->pen().color()
+ );
+
+ m_lenseLaserIntersectionItem = new QGraphicsEllipseItem{
+ QRectF{QPointF{-1, -1}, QPointF{1, 1}},
+ m_lenseItem
+ };
+ m_lenseLaserIntersectionItem->setPen(QPen{Qt::blue, 0});
+
+ const auto lenseLaserTextItem = new QGraphicsTextItem{
+ tr("Scheimpflug: lense/laser"),
+ m_lenseLaserIntersectionItem
+ };
+
+ lenseLaserTextItem->setPos(QPointF{-6, -2});
+ lenseLaserTextItem->setFont(font);
+ lenseLaserTextItem->setDefaultTextColor(
+ m_lenseLaserIntersectionItem->pen().color()
+ );
}
void GraphicsScene::update(OpticalDesign* design)
{
+ qDebug() << "update";
if (!design)
{
qCritical() << Q_FUNC_INFO << "design is nullptr";
@@ -229,4 +268,162 @@ void GraphicsScene::update(OpticalDesign* design)
);
// TODO: take back focal length into account
+
+ // check Scheimpflug principle
+ // TODO: draw lines?
+ QPointF sensorLenseIntersection{};
+
+ if (m_sensorItem->line().intersects(
+ m_lineOfActionItem->line(),
+ &sensorLenseIntersection
+ ) == QLineF::NoIntersection)
+ {
+ qWarning() << "no intersection between sensor plane and lense plane";
+ return;
+ }
+
+ m_sensorLenseIntersectionItem->setPos(sensorLenseIntersection);
+
+ QPointF lenseLaserIntersection{};
+
+ if (m_lineOfActionItem->line().intersects(
+ m_actualRangeItem->line(),
+ &lenseLaserIntersection
+ ) == QLineF::NoIntersection)
+ {
+ qWarning() << "no intersection between laser plane and lense plane";
+ return;
+ }
+
+ m_lenseLaserIntersectionItem->setPos(lenseLaserIntersection);
+
+ if (!qFuzzyCompare(sensorLenseIntersection, lenseLaserIntersection))
+ {
+ qWarning() << "The Scheimpflug principle is not observed:" << Qt::endl
+ << "sensor/lense intersection:" << sensorLenseIntersection
+ << Qt::endl
+ << "lense/laser intersection:" << lenseLaserIntersection;
+ }
+
+ // TODO: move to settings
+ // doesn't work (doesn't zoom)
+ constexpr bool autoScale{false};
+
+ if (autoScale)
+ {
+ // region of interest
+ QRectF ROI{};
+
+ ROI |= m_actualRangeAreaItem->boundingRect();
+ ROI |= m_desiredRangeAreaItem->boundingRect();
+ ROI |= m_lenseItem->boundingRect();
+ ROI |= m_sensorItem->boundingRect();
+ ROI |= m_sensorLenseIntersectionItem->boundingRect();
+ ROI |= m_lenseLaserIntersectionItem->boundingRect();
+
+ for (const auto& view : views())
+ {
+ // TODO: move to settings
+ constexpr double margin{5.};
+ view->setSceneRect(ROI);
+ }
+ }
+
+ // calculate distance between sensor and lense on optical axis
+ QPointF sensorAxisIntersection{};
+
+ if (m_sensorItem->line().intersects(
+ m_opticalAxisItem->line(),
+ &sensorAxisIntersection
+ ) == QLineF::NoIntersection)
+ {
+ qCritical() << "no intersection between sensor and optical axis";
+ return;
+ }
+
+ design->set_lenseSensorDistanceMm(
+ QLineF{QPointF{0, 0}, sensorAxisIntersection}.length()
+ );
+
+ // calculate depth of field
+ QPointF axisLaserIntersection{};
+
+ if (m_opticalAxisItem->line().intersects(
+ m_actualRangeItem->line(),
+ &axisLaserIntersection
+ ) == QLineF::NoIntersection)
+ {
+ qCritical() << "no intersection between laser and optical axis";
+ return;
+ }
+
+ // const auto zM = std::min(
+ // design->get_sensorPixelsHeight(),
+ // design->get_sensorPixelsWidth()
+ // ) /
+ // 1000. / 1000.;
+
+ // try z based on sensor cell size
+ // const auto zMm = std::min(
+ // design->get_sensorCellHeightUm(),
+ // design->get_sensorCellHeightUm()
+ // ) /
+ // 1000.;
+ // try z based on 1/16 sensor cell size (calibration step)
+ const auto zMm = std::min(
+ design->get_sensorCellHeightUm(),
+ design->get_sensorCellWidthUm()
+ ) /
+ 1000. / 16.;
+
+ // try z based on E. Goldovsky method - 0.2% of sensor height
+ // const auto zMm = design->get_sensorHeightMm() * 0.2 / 100.;
+ // const auto RM =
+ // QLineF{QPointF{0., 0.}, axisLaserIntersection}.length() * 1000.;
+ const auto RMidMm = QLineF{QPointF{0., 0.}, axisLaserIntersection}.length();
+ // const auto RFrontMm = QLineF{QPointF{0., 0.},
+ // axisLaserIntersection}.length(); const auto fM =
+ // design->get_backFocalDistanceMm() * 1000.;
+
+ // Gordijchuk & Pell, 1979, say to use focal distance.
+ // Wikipedia, based on the same book, says to use back focal distance. WTF?
+ // const auto fMm = design->get_backFocalDistanceMm();
+ const auto fMm = design->get_focalDistanceMm();
+
+ const auto K = static_cast<int>(design->get_lenseAperture()) / 10.;
+
+ using FromSharpDistMm = double;
+ using BackSharpDistMm = double;
+ using DofResult = std::tuple<FromSharpDistMm, BackSharpDistMm>;
+ const auto calculateDof = [zMm, fMm, K](const auto RMm) -> DofResult {
+ const auto ff = fMm * fMm;
+ const auto Rff = RMm * ff;
+ const auto Kfz = K * fMm * zMm;
+ const auto KRz = K * RMm * zMm;
+
+ const auto R1Mm = Rff / (ff - Kfz + KRz);
+ const auto R2Mm = Rff / (ff + Kfz - KRz);
+
+ return {R1Mm, R2Mm};
+ };
+
+ const auto ff = fMm * fMm;
+ const auto Rff = RMidMm * ff;
+ const auto Kfz = K * fMm * zMm;
+ const auto KRz = K * RMidMm * zMm;
+
+ // const auto R1M = Rff / (ff - Kfz + KRz);
+ // const auto R2M = Rff / (ff + Kfz - KRz);
+
+ // const auto R1Mm = Rff / (ff - Kfz + KRz);
+ // const auto R2Mm = Rff / (ff + Kfz - KRz);
+
+ const auto [R1Mm, R2Mm] = calculateDof(RMidMm);
+
+ qDebug() << "AAAAA: update" << R1Mm << R2Mm
+ << design->get_sensorCellHeightUm();
+
+ design->set_frontSharpDistanceMm(R1Mm);
+ design->set_backSharpDistanceMm(R2Mm);
+ design->set_depthOfFieldMm((R2Mm - R1Mm));
}