QList<GLC_Point2d> glc::normalyzePolygon(const QList<GLC_Point2d>& polygon) { QList<GLC_Point2d> subject; const int count= polygon.count(); Q_ASSERT(count > 2); GLC_Point2d minPoint= polygon.first(); GLC_Point2d maxPoint= minPoint; for (int i= 1; i < count; ++i) { GLC_Point2d point= polygon.at(i); minPoint.setX(qMin(point.x(), minPoint.x())); minPoint.setY(qMin(point.y(), minPoint.y())); maxPoint.setX(qMax(point.x(), maxPoint.x())); maxPoint.setY(qMax(point.y(), maxPoint.y())); } const GLC_Vector2d range= maxPoint - minPoint; Q_ASSERT(range.x() != 0.0); Q_ASSERT(range.y() != 0.0); for (int i= 0; i < count; ++i) { const GLC_Point2d point= polygon.at(i); const GLC_Point2d temp= (point - minPoint); const GLC_Point2d result(temp.x() / range.x(), temp.y() / range.y()); subject.append(result); } return subject; }
GLC_Point2d GLC_Viewport::project(const GLC_Point3d &point, bool useCameraMatrix) const { GLC_Matrix4x4 modelView; GLC_Matrix4x4 projectionMatrix; GLint viewport[4]= {0, 0, m_Width, m_Height}; if (useCameraMatrix) { modelView= m_pViewCam->modelViewMatrix(); projectionMatrix= m_ProjectionMatrix; } else { modelView= GLC_Context::current()->modelViewMatrix(); glGetIntegerv(GL_VIEWPORT, viewport); projectionMatrix= GLC_Context::current()->projectionMatrix(); } double x; double y; double z; glc::gluProject(point.x(), point.y(), point.z(), modelView.getData(), projectionMatrix.getData(), viewport, &x, &y, &z); GLC_Vector2d subject; subject.setX(x); subject.setY(y); return subject; }
// find intersection between two 2D segments QVector<GLC_Point2d> glc::findIntersection(const GLC_Point2d& s1p1, const GLC_Point2d& s1p2, const GLC_Point2d& s2p1, const GLC_Point2d& s2p2) { const GLC_Vector2d D0= s1p2 - s1p1; const GLC_Vector2d D1= s2p2 - s2p1; // The QVector of result points QVector<GLC_Point2d> result; const GLC_Vector2d E(s2p1 - s1p1); double kross= D0 ^ D1; double sqrKross= kross * kross; const double sqrLen0= D0.x() * D0.x() + D0.y() * D0.y(); const double sqrLen1= D1.x() * D1.x() + D1.y() * D1.y(); // Test if the line are nor parallel if (sqrKross > (EPSILON * sqrLen0 * sqrLen1)) { const double s= (E ^ D1) / kross; if ((s < 0.0) || (s > 1.0)) { // Intersection of lines is not a point on segment s1p1 + s * DO return result; // Return empty QVector } const double t= (E ^ D0) / kross; if ((t < 0.0) || (t > 1.0)) { // Intersection of lines is not a point on segment s2p1 + t * D1 return result; // Return empty QVector } // Intersection of lines is a point on each segment result << (s1p1 + (D0 * s)); return result; // Return a QVector of One Point } // Lines of the segments are parallel const double sqrLenE= E.x() * E.x() + E.y() * E.y(); kross= E ^ D0; sqrKross= kross * kross; if (sqrKross > (EPSILON * sqrLen0 * sqrLenE)) { // Lines of the segments are different return result; // Return empty QVector } // Lines of the segments are the same. Need to test for overlap of segments. const double s0= (D0 * E) / sqrLen0; const double s1= (D0 * D1) / sqrLen0; const double sMin= qMin(s0, s1); const double sMax= qMax(s0, s1); QVector<double> overlaps= findIntersection(0.0, 1.0, sMin, sMax); const int iMax= overlaps.size(); for (int i= 0; i < iMax; ++i) { result.append(s1p1 + (D0 * overlaps[i])); } return result; }
GLC_Vector2d round(const GLC_Vector2d& vector, double accuracy) { GLC_Vector2d subject(glc::round(vector.x(), accuracy), glc::round(vector.y(), accuracy)); return subject; }
GLC_Vector2d round(const GLC_Vector2d& vector) { GLC_Vector2d subject(glc::round(vector.x()), glc::round(vector.y())); return subject; }
bool glc::compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2, double accuracy) { bool compareResult= (qAbs(v1.x() - v2.x()) <= accuracy); return compareResult && (qAbs(v1.y() - v2.y()) <= accuracy); }
bool glc::compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2) { bool compareResult= (qAbs(v1.x() - v2.x()) <= comparedPrecision); return compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision); }
// return true if there is an intersection between a ray and a segment bool glc::isIntersectedRaySegment(const GLC_Point2d& s1p1, const GLC_Vector2d& s1p2, const GLC_Point2d& s2p1, const GLC_Point2d& s2p2) { const GLC_Vector2d D0= s1p2 - s1p1; const GLC_Vector2d D1= s2p2 - s2p1; const GLC_Vector2d E(s2p1 - s1p1); double kross= D0 ^ D1; double sqrKross= kross * kross; const double sqrLen0= D0.x() * D0.x() + D0.y() * D0.y(); const double sqrLen1= D1.x() * D1.x() + D1.y() * D1.y(); // Test if the line are nor parallel if (sqrKross > (EPSILON * sqrLen0 * sqrLen1)) { const double s= (E ^ D1) / kross; if ((s < 0.0)) { // Intersection of lines is not a point on segment s1p1 + s * DO return false; } const double t= (E ^ D0) / kross; if ((t < 0.0) || (t > 1.0)) { // Intersection of lines is not a point on segment s2p1 + t * D1 return false; } // Intersection of lines is a point on each segment return true; } // Lines of the segments are parallel const double sqrLenE= E.x() * E.x() + E.y() * E.y(); kross= E ^ D0; sqrKross= kross * kross; if (sqrKross > (EPSILON * sqrLen0 * sqrLenE)) { // Lines of are different return false; } else return true; }
// return true if there is an intersection between 2 segments bool glc::isIntersected(const GLC_Point2d& s1p1, const GLC_Point2d& s1p2, const GLC_Point2d& s2p1, const GLC_Point2d& s2p2) { const GLC_Vector2d D0= s1p2 - s1p1; const GLC_Vector2d D1= s2p2 - s2p1; const GLC_Vector2d E(s2p1 - s1p1); double kross= D0 ^ D1; double sqrKross= kross * kross; const double sqrLen0= D0.x() * D0.x() + D0.y() * D0.y(); const double sqrLen1= D1.x() * D1.x() + D1.y() * D1.y(); // Test if the line are nor parallel if (sqrKross > (EPSILON * sqrLen0 * sqrLen1)) { const double s= (E ^ D1) / kross; if ((s < 0.0) || (s > 1.0)) { // Intersection of lines is not a point on segment s1p1 + s * DO return false; } const double t= (E ^ D0) / kross; if ((t < 0.0) || (t > 1.0)) { // Intersection of lines is not a point on segment s2p1 + t * D1 return false; } // Intersection of lines is a point on each segment return true; } // Lines of the segments are parallel const double sqrLenE= E.x() * E.x() + E.y() * E.y(); kross= E ^ D0; sqrKross= kross * kross; if (sqrKross > (EPSILON * sqrLen0 * sqrLenE)) { // Lines of the segments are different return false; } // Lines of the segments are the same. Need to test for overlap of segments. const double s0= (D0 * E) / sqrLen0; const double s1= s0 + (D0 * D1) / sqrLen0; const double sMin= qMin(s0, s1); const double sMax= qMax(s0, s1); if (findIntersection(0.0, 1.0, sMin, sMax).size() == 0) return false; else return true; }