/** * @RDE_HEADER@ * Helper functions related to CoordinateTranslation * $Id$ * $HeadURL$ * $Author$ */ // Own #include "simple_helper.h" #include "math_const.h" #include "clipper.hpp" #include // Qt #include #include namespace SituationMap { namespace MathUtils { QPointF rotate(const QPointF &p, const QPointF ¢er, qreal sinA, qreal cosA) { qreal x = p.x() - center.x(); qreal y = p.y() - center.y(); return QPointF(x * cosA - y * sinA + center.x(), y * cosA + x * sinA + center.y()); } QPointF rotate(const QPointF &p, const QPointF ¢er, qreal phi) { return rotate(p, center, sin(phi), cos(phi)); } qreal getMathAngle(qreal sinPhi, qreal cosPhi) { qreal phi = acos(cosPhi); if (sinPhi < 0) phi = MathConst::pi_two - phi; return phi; } qreal getMathAngle(const QPointF &oVec) { return getMathAngle(oVec.y(), oVec.x()); } double getAngleDegreeNorth(const QPointF &p1, const QPointF &p2) { double x = p2.x() - p1.x(); double y = p2.y() - p1.y(); // Winkel der Geraden bestimmen double alphaRad = atan2(y, x); // // Fuer Winkel > PI liefert atan2 math. rechts drehende (also negative) Werte. // // Um Werte von 0-2PI zu bekommen muss deshalb hier von 2Pi abgezogen werden. alphaRad -= M_PI / 2.0; alphaRad *= -1.0; if (alphaRad < 0.0) alphaRad = 2 * M_PI + alphaRad; return (alphaRad * 180.0 / M_PI); } QPointF getPointOnLine(const QPointF &p1, const QPointF &p2, double position_0_to_1) { QPointF pRet; pRet.rx() = p1.x() + (p2.x() - p1.x()) * position_0_to_1; pRet.ry() = p1.y() + (p2.y() - p1.y()) * position_0_to_1; return pRet; } Point3D getPointOnLine(const Point3D &p1, const Point3D &p2, double position_0_to_1) { Point3D pRet; pRet.rx() = p1.x() + (p2.x() - p1.x()) * position_0_to_1; pRet.ry() = p1.y() + (p2.y() - p1.y()) * position_0_to_1; pRet.rz() = p1.z() + (p2.z() - p1.z()) * position_0_to_1; return pRet; } void rotatePoint(QPointF &pToBeRotated, const QPointF ¢er, double angleDegree) { // angle to rad double radAngle = ((M_PI) / -180.0) * angleDegree; // Translate QPointF t = pToBeRotated - center; // Rotate QPointF tmp; tmp.rx() = t.x() * cos(radAngle) - t.y() * sin(radAngle); tmp.ry() = t.x() * sin(radAngle) + t.y() * cos(radAngle); // Translate back and write result pToBeRotated = tmp + center; } QList mineFieldCenterLineToOutline(const QList ¢erLine, double width) { QList outline; // Clipper is using ints (typedef signed long long cInt;) // The coordinate of centerline will have values much lower the the maximum. // Therefore the factor can be 1000. So the resolution is bit enough (->Millimeter): const int factorInt = 10; const double factorDouble = 10.0; ClipperLib::ClipperOffset pathOffset; ClipperLib::Path borderPath; // vector< int > ClipperLib::Paths offsetPathVec; // vector< vector< int > > for (auto point : centerLine) { borderPath << ClipperLib::IntPoint(static_cast(point.x()*factorInt), static_cast(point.y()*factorInt)); } pathOffset.AddPath(borderPath, ClipperLib::JoinType::jtSquare, ClipperLib::EndType::etOpenButt); pathOffset.Execute(offsetPathVec, static_cast(fabs(width)*factorInt)); for (auto path : offsetPathVec) { ClipperLib::Path::const_iterator it = path.begin(); for (; it != path.end(); ++it) { outline.append(QPointF(static_cast(it->X) / factorDouble, static_cast(it->Y) / factorDouble) ); } } return outline; } qreal getAngleDegree2North(qreal angleDeg) { double rotationAngle = angleDeg < 360. ? angleDeg : std::fmod(angleDeg, 360.); // set rotation to 0° North(12h) counter clock wise rotationAngle = rotationAngle < 90. ? std::fabs(90 - rotationAngle) : std::fabs(360 - rotationAngle + 90) ; return rotationAngle; } qreal getAngleDegree2Math(qreal angleDeg) { // set rotation to 0° math(3h) clockwise const double rotationMath = angleDeg < 90. ? std::fabs(angleDeg - 90) : std::fabs(360 - angleDeg + 90) ; return rotationMath; } QPolygonF getCircleSectorPolygon(const QPointF ¢erPoint, qreal radius, double rotationAngleDeg, double centralAngleDeg) { // | <-rotationAngle // | .\ | / const double angleRad = angle * LtsCoordTrans::deg2rad(); // relPosition des StartPoint (point on circle) const QPointF position(cos(angleRad) * radius, sin(angleRad) * radius); // StartPoint einfügen poly << centerUtm.geographic(position); // calculate all steps, inclusive EndPos for (int step = 1; step<=steps; ++step) { double curAngle = angle + (step*singleIncrementDegree); double curAngleRad = curAngle * LtsCoordTrans::deg2rad(); poly << centerUtm.geographic( QPointF(cos(curAngleRad) * radius, sin(curAngleRad) * radius) ); } // for return poly; } } // namespace SituationMap::MathUtils } // namespace SituationMap