diff options
| -rw-r--r-- | src/gldisc.cpp | 65 | ||||
| -rw-r--r-- | src/mmscene.cpp | 4 |
2 files changed, 63 insertions, 6 deletions
diff --git a/src/gldisc.cpp b/src/gldisc.cpp index a2c22b5..85dd6d4 100644 --- a/src/gldisc.cpp +++ b/src/gldisc.cpp @@ -29,10 +29,10 @@ void GLDisc::makeSurface(QVector<GLPoint> *pointContainer, m_points->append(GLPoint(m_circleRadius * tmp, -v_Z, tmpTextCoo, m_color)); m_points->append(GLPoint(m_circleRadius * tmp, tmp, tmpTextCoo, m_color)); - m_points->append(GLPoint(QVector3D(m_circleRadius * tmp, m_height), tmp, tmpTextCoo, - m_color)); - m_points->append(GLPoint(QVector3D(m_circleRadius * tmp, m_height), v_Z, tmpTextCoo, - m_color)); + m_points->append(GLPoint(QVector3D(m_circleRadius * tmp, m_height), tmp, + tmpTextCoo, m_color)); + m_points->append(GLPoint(QVector3D(m_circleRadius * tmp, m_height), v_Z, + tmpTextCoo, m_color)); } m_points->append(GLPoint(m_height * v_Z, v_Z, QVector3D(0.5, 0.5, 0.0), @@ -82,12 +82,67 @@ void GLDisc::makeSurface(QVector<GLPoint> *pointContainer, bool GLDisc::isHit(QVector3D p1, QVector3D p2) { - if(!GLBody::isHit(p1, p2)) + if (!GLBody::isHit(p1, p2)) { return false; } + QVector3D lineVector = p2 - p1; + // Calculate intersection point with the xy plane + QVector3D vecBottom = p1 + lineVector * (-p1.z() / lineVector.z()); + + if (vecBottom.length() < m_circleRadius) + { + return true; + } + + // Calculate intersection point with the xy + m_heigth plane + // Then drop z so that we get a projection onto the xy plane + QVector3D vecTop = (p1 + lineVector * ((m_height - p1.z()) / + lineVector.z())).toVector2D(); + + if (vecTop.length() < m_circleRadius) + { + return true; + } + + // Check if the mouse line is hitting the outer disc side + QVector2D vecXYProjection = lineVector.toVector2D(); + QVector2D vecXYStart = p1.toVector2D(); + + // Solved via the "Mitternachtsformel" + float a = QVector2D::dotProduct(vecXYProjection, vecXYProjection); + float b = 2 * QVector2D::dotProduct(vecXYStart, vecXYProjection); + float c = QVector2D::dotProduct(vecXYStart, + vecXYStart) - m_circleRadius * m_circleRadius; + + float discriminant = b * b - 4 * a * c; + + if (discriminant >= 0) + { + discriminant = sqrt(discriminant); + + float lambda1 = (-b - discriminant) / (2*a); + + float z1 = (p1 + lambda1 * lineVector).z(); + + if(z1 >= 0 && z1 <= m_height) + { + return true; + } + + float lambda2 = (-b + discriminant) / (2*a); + + float z2 = (p1 + lambda2 * lineVector).z(); + + if(z2 >= 0 && z2 <= m_height) + { + return true; + } + } + + return false; } QVector2D GLDisc::calculatePoint(double sideAngle) diff --git a/src/mmscene.cpp b/src/mmscene.cpp index ccae5a5..1554e83 100644 --- a/src/mmscene.cpp +++ b/src/mmscene.cpp @@ -76,7 +76,9 @@ void MMScene::setupGeometry() void MMScene::mousePressed(int x, int y) { renderer()->calculateMousePoints(&m_MouseNear, &m_mouseFar, QPoint(x, y)); - renderer()->mouseIntersection(&m_lastIntersection, v_Y, 0.0, QPoint(x, y)); //get starting point + renderer()->mouseIntersection(&m_lastIntersection, v_Z, 0.0, QPoint(x, y)); //get starting point + if (m_disc->isHit(m_MouseNear, m_mouseFar)) + qDebug() << "Treffer"; } void MMScene::drawTriangles() |
