00001
00002
00003
00004
00005
00006
00007 #include "CallbackPointOrdinal.h"
00008 #include "EngaugeAssert.h"
00009 #include "Logger.h"
00010 #include "mmsubs.h"
00011 #include "Point.h"
00012 #include <qmath.h>
00013 #include "Transformation.h"
00014
00015 CallbackPointOrdinal::CallbackPointOrdinal(const LineStyle &lineStyle,
00016 const Transformation &transformation,
00017 const QPointF &posScreen) :
00018 m_lineStyle (lineStyle),
00019 m_transformation (transformation),
00020 m_posScreen (posScreen),
00021 m_haveMinimumDistanceToLine (false),
00022 m_minimumDistanceToLine (0.0),
00023 m_minimumProjectedDistanceOutsideLine (0.0),
00024 m_ordinal (0)
00025 {
00026 }
00027
00028 CallbackSearchReturn CallbackPointOrdinal::callback (const Point &pointStart,
00029 const Point &pointStop)
00030 {
00031 double xProjection, yProjection, projectedDistanceOutsideLine, distanceToLine;
00032
00033 projectPointOntoLine(m_posScreen.x(),
00034 m_posScreen.y(),
00035 pointStart.posScreen().x(),
00036 pointStart.posScreen().y(),
00037 pointStop.posScreen().x(),
00038 pointStop.posScreen().y(),
00039 &xProjection,
00040 &yProjection,
00041 &projectedDistanceOutsideLine,
00042 &distanceToLine);
00043
00044
00045 if (!m_haveMinimumDistanceToLine ||
00046 (distanceToLine < m_minimumDistanceToLine) ||
00047 (distanceToLine == m_minimumDistanceToLine && projectedDistanceOutsideLine < m_minimumProjectedDistanceOutsideLine)) {
00048
00049
00050 if (projectedDistanceOutsideLine == 0) {
00051
00052
00053 m_ordinal = (pointStart.ordinal() + pointStop.ordinal()) / 2.0;
00054
00055 } else {
00056
00057
00058 double distanceProjectionToStart = qSqrt ((xProjection - pointStart.posScreen().x()) * (xProjection - pointStart.posScreen().x()) +
00059 (yProjection - pointStart.posScreen().y()) * (yProjection - pointStart.posScreen().y()));
00060 double distanceProjectionToStop = qSqrt ((xProjection - pointStop.posScreen().x()) * (xProjection - pointStop.posScreen().x()) +
00061 (yProjection - pointStop.posScreen().y()) * (yProjection - pointStop.posScreen().y()));
00062 if (distanceProjectionToStart < distanceProjectionToStop) {
00063
00064
00065 m_ordinal = pointStart.ordinal() - 0.5;
00066
00067 } else {
00068
00069
00070 m_ordinal = pointStop.ordinal() + 0.5;
00071 }
00072 }
00073
00074
00075 m_haveMinimumDistanceToLine = true;
00076 m_minimumDistanceToLine = distanceToLine;
00077 m_minimumProjectedDistanceOutsideLine = projectedDistanceOutsideLine;
00078 }
00079
00080 return CALLBACK_SEARCH_RETURN_CONTINUE;
00081 }
00082
00083 double CallbackPointOrdinal::ordinal () const
00084 {
00085 return m_ordinal;
00086 }