рдХреНрдпреВрдПрдордПрд▓ рдореИрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд┐рд▓реНрдб рдПрдпрд░рд╡реЗрдЬ рдХреЗ рд▓рд┐рдП - рднрд╛рдЧ 1

рдкрд┐рдЫрд▓реЗ рдХреБрдЫ рд╕рдордп рд╕реЗ рдореИрдВ рдЧреНрд░рд╛рдлрд╝рд┐рдХрд▓ рдЗрдВрдЯрд░рдлреЗрд╕ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпреВрдПрдордПрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЕрднреА рддрдХ рдХреНрдпреВрдЯреА рд▓реЛрдХреЗрд╢рди рдПрдкреАрдЖрдИ рдФрд░ рдХреНрдпреВрдПрдордПрд▓ рдореИрдк рдХреЗ рд╕рд╛рде рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдЕрд╡рд╕рд░ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рд╡рд╛рдпреБрдорд╛рд░реНрдЧ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдЗрд╕ рдШрдЯрдХ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдирд╛ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛ рдЧрдпрд╛ред
рдХрдЯрд░ рдХреЗ рддрд╣рдд рдорд╛рдирдЪрд┐рддреНрд░ рдкрд░ рд╕рдорд╛рди рдкрде рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдкрд╛рджрдХ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╡рд░реНрдгрди рд╣реИ:

рдЫрд╡рд┐

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рд╡рд┐рдорд╛рди рдПрдХ рд╣реА рдКрдВрдЪрд╛рдИ рдкрд░ 2 рдбреА рд╡рд┐рдорд╛рди рдореЗрдВ рдЙрдбрд╝рддреЗ рд╣реИрдВред рдЧрддрд┐ рдФрд░ рдЕрдиреБрдореЗрдп рдЕрдзрд┐рднрд╛рд░ рддрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ - 920 рдХрд┐рдореА / рдШрдВрдЯрд╛ рдФрд░ 3 рдЬреА, рдЬреЛ рдПрдХ рдореЛрдбрд╝ рддреНрд░рд┐рдЬреНрдпрд╛ рджреЗрддрд╛ рд╣реИ

R= fracv2G=21770m


рдкреНрд░рдХреНрд╖реЗрдкрд╡рдХреНрд░ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЦрдВрдб рд╣реЛрддреЗ рд╣реИрдВ:
рдЫрд╡рд┐
рдЬрд╣рд╛рдВ S рдкреИрдВрддрд░реЗрдмрд╛рдЬрд╝реА рдХреА рд╢реБрд░реБрдЖрдд рд╣реИ (рдпрд╣ рдкрд┐рдЫрд▓реЗ рдПрдХ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХрд╛ рдмрд┐рдВрджреБ рд╣реИ), M рдореЛрдбрд╝ рдХреА рд╢реБрд░реБрдЖрдд рд╣реИ, E рдЗрд╕рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рд╡рд╛рд▓рд╛ рд╣реИ, рдФрд░ F рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рд╣реИ (рдЕрдЧрд▓реЗ рдХреЗ рд▓рд┐рдП M)ред

рдкреНрд░рдХреНрд╖реЗрдкрд╡рдХреНрд░ рд╕реЗ рдкреНрд░рд╡реЗрд╢ рдФрд░ рдирд┐рдХрд╛рд╕ рдХреЗ рдмрд┐рдВрджреБ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рд╡реГрддреНрдд рдХреЗ рд╕реНрдкрд░реНрд╢рд░реЗрдЦрд╛ рдХреЗ рд╕рдореАрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рдЧрдгрдирд╛рдПрдВ рдмреЛрдЭрд┐рд▓ рд╣реЛ рдЧрдИрдВ, рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ рдЗрд╕реЗ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

void Manoeuvre::calculate() { // General equation of line between first and middle points auto A = mStart.y() - mMiddle.y(); auto B = mMiddle.x() - mStart.x(); // Check cross product sign whether final point lies on left side auto crossProduct = (B*(mFinal.y() - mStart.y()) + A*(mFinal.x() - mStart.x())); // All three points lie on the same line if (isEqualToZero(crossProduct)) { mIsValid = true; mCircle = mExit = mMiddle; return; } mIsLeftTurn = crossProduct > 0; auto lineNorm = A*A + B*B; auto exitSign = mIsLeftTurn ? 1 : -1; auto projection = exitSign*mRadius * qSqrt(lineNorm); // Center lies on perpendicular to middle point if (!isEqualToZero(A) && !isEqualToZero(B)) { auto C = -B*mStart.y() - A*mStart.x(); auto right = (projection - C)/A - (mMiddle.x()*lineNorm + A*C) / (B*B); mCircle.ry() = right / (A/B + B/A); mCircle.rx() = (projection - B*mCircle.y() - C) / A; } else { // Entering line is perpendicular to either x- or y-axis auto deltaY = isEqualToZero(A) ? 0 : exitSign*mRadius; auto deltaX = isEqualToZero(B) ? 0 : exitSign*mRadius; mCircle.ry() = mMiddle.y() + deltaY; mCircle.rx() = mMiddle.x() + deltaX; } // Check if final point is outside manouevre circle auto circleDiffX = mFinal.x() - mCircle.x(); auto circleDiffY = mFinal.y() - mCircle.y(); auto distance = qSqrt(circleDiffX*circleDiffX + circleDiffY*circleDiffY); mIsValid = distance > mRadius; // Does not make sence to calculate futher if (!mIsValid) return; // Length of hypotenuse from final point to exit point auto beta = qAtan2(mCircle.y() - mFinal.y(), mCircle.x() - mFinal.x()); auto alpha = qAsin(mRadius / distance); auto length = qSqrt(distance*distance - mRadius*mRadius); // Depends on position of final point find exit point mExit.rx() = mFinal.x() + length*qCos(beta + exitSign*alpha); mExit.ry() = mFinal.y() + length*qSin(beta + exitSign*alpha); // Finally calculate start/span angles auto startAngle = qAtan2(mCircle.y() - mMiddle.y(), mMiddle.x() - mCircle.x()); auto endAngle = qAtan2(mCircle.y() - mExit.y(), mExit.x() - mCircle.x()); mStartAngle = startAngle < 0 ? startAngle + 2*M_PI : startAngle; endAngle = endAngle < 0 ? endAngle + 2*M_PI : endAngle; auto smallSpan = qFabs(endAngle - mStartAngle); auto bigSpan = 2*M_PI - qFabs(mStartAngle - endAngle); bool isZeroCrossed = mStartAngle > endAngle; if (!mIsLeftTurn) { mSpanAngle = isZeroCrossed ? bigSpan : smallSpan; } else { mSpanAngle = isZeroCrossed ? smallSpan : bigSpan; } } 

рд╣рдорд╛рд░реЗ рдкреНрд░рдХреНрд╖реЗрдкрд╡рдХреНрд░ рдХреЗ рдЧрдгрд┐рддреАрдп рдореЙрдбрд▓ рдХрд╛ рдорд┐рд╕рдХреЙрд▓ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рд╕реАрдзреЗ рдореИрдк рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рдХреНрдпреВрдПрдордПрд▓ рдирдХреНрд╢реЗ рдкрд░ рдкреЙрд▓реАрдЗрдиреНрд╕ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рд╛рдХреГрддрд┐рдХ рд╡рд┐рдХрд▓реНрдк рд╣реИ рдореИрдк рдореЗрдВ рд╕реАрдзреЗ рдореИрдкрдкреЙрд▓рд╛рдЗрди рдХреЛ рдЬреЛрдбрд╝рдирд╛ред

 Map { id: map plugin: Plugin { name: "osm" } MapPolyline { path: [ { latitude: -27, longitude: 153.0 }, ... ] } } 

рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдореИрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдорд╛рд░реНрдЧ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдж рдХреЗ рдЕрдиреБрднрд╛рдЧ рдХреЛ "рдордХреНрдЦреА рдкрд░" рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ - рдХрд░реНрд╕рд░ рдХреЗ рдкреАрдЫреЗ рдкреНрд░рдХреНрд╖реЗрдк рдкрде рдХреЗ рдкреНрд░рднрд╛рд╡ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдПред

рдЫрд╡рд┐

рдХрд░реНрд╕рд░ рдХреЛ рд▓реЗ рдЬрд╛рдиреЗ рдкрд░ рдкрде рдмрджрд▓рдирд╛ рдПрдХ рдорд╣рдВрдЧрд╛ рдСрдкрд░реЗрд╢рди рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ "рдкрд┐рдХреНрд╕реЗрд▓" рдкрде рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдЬреЛ рддрдм рддрдХ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдВрддрддрдГ рдорд╛рд░реНрдЧ рдХреЛ рдирд╣реАрдВ рдмрдЪрд╛рддрд╛ред

 Repeater { id: trajectoryView model: flightRegistry.hasActiveFlight ? flightRegistry.flightModel : [] FlightItem { anchors.fill: parent startPoint: start endPoint: end manoeuvreRect: rect manoeuvreStartAngle: startAngle manoeuvreSpanAngle: spanAngle isVirtualLink: isVirtual } } 

FlightItem рдПрдХ QQuickItem рд╣реИ , рдФрд░ QAbstractListModel FlightModel рдЖрдкрдХреЛ рдкреИрдВрддрд░реЗрдмрд╛рдЬрд╝реА рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдмрджрд▓рддреЗ рд╕рдордп рдкреНрд░рдХреНрд╖реЗрдкрд╡рдХреНрд░ рдХреЗ рдЖрд╡рд╢реНрдпрдХ рд╡рд░реНрдЧреЛрдВ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

 QVariant FlightModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } switch (role) { case FlightRoles::StartPoint: return mFlight->flightSegment(index.row()).line().p1(); case FlightRoles::EndPoint: return mFlight->flightSegment(index.row()).line().p2(); ... } 

рдРрд╕рд╛ рд▓рд╛рдЗрд╡ рдЕрдкрдбреЗрдЯ рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЕрд╡рд╛рд╕реНрддрд╡рд┐рдХ рдпреБрджреНрдзрд╛рднреНрдпрд╛рд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдЫрд╡рд┐

рд╡рд╛рдпреБрдорд╛рд░реНрдЧ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рд╣реА (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рджрд╛рдПрдВ рдорд╛рдЙрд╕ рдХреНрд▓рд┐рдХ рдХреЗ рд╕рд╛рде) рдорд╛рд░реНрдЧ рдХреЛ рдЕрдВрддрддрдГ рдХреНрдпреВрдПрдордПрд▓ рдореИрдк рдореЗрдВ рдЬрд┐рдпреЛрдкреИрде рдХреЗ рд░реВрдк рдореЗрдВ рднреВ-рдЧрддрд┐ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ (рдЬрдм рддрдХ рдХрд┐ рдЗрд╕ рдХреНрд╖рдг рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЬрд╝реВрдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдкрд┐рдХреНрд╕рд▓ рдХреЛ рджреЗрд╢рд╛рдВрддрд░ рдФрд░ рдЕрдХреНрд╖рд╛рдВрд╢ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдкрддрд╛ рдирд╣реАрдВ рд╣реИ)ред
рдПрдХ рдкрд┐рдХреНрд╕реЗрд▓ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЛ рдЬрд┐рдпреЛ-рдХреЛрдСрд░реНрдбрд┐рдиреЗрдЯ рдореЗрдВ рдкреБрдирд░реНрдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреИрдВрддрд░реЗрдмрд╛рдЬрд╝реА рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдордиреНрд╡рдп рдкреНрд░рдгрд╛рд▓реА рд╕реНрдерд╛рдиреАрдп рдХреЗ рд▓рд┐рдП рдкреИрдВрддрд░реЗрдмрд╛рдЬрд╝реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ (рд╣рдорд╛рд░рд╛ рдмрд┐рдВрджреБ рдПрд╕)ред

 QPointF FlightGeoRoute::toPlaneCoordinate(const QGeoCoordinate &origin, const QGeoCoordinate &point) { auto distance = origin.distanceTo(point); auto azimuth = origin.azimuthTo(point); auto x = qSin(qDegreesToRadians(azimuth)) * distance; auto y = qCos(qDegreesToRadians(azimuth)) * distance; return QPointF(x, y); } 

рд╣рдо рдкреИрдВрддрд░реЗрдмрд╛рдЬрд╝реА рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдореАрдЯрд░ рдореЗрдВ рдкреБрдирд░реНрдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд░рд┐рд╡рд░реНрд╕ рдСрдкрд░реЗрд╢рди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдФрд░ рдореАрдЯрд░ рдПрд╕ рдХреЛ рдЕрдХреНрд╖рд╛рдВрд╢-рджреЗрд╢рд╛рдВрддрд░ рдкрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯ рдПрд╕ рдХреЗ рднреВ-рд╕рдВрджрд░реНрдн рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВред

 QGeoCoordinate FlightGeoRoute::toGeoCoordinate(const QGeoCoordinate &origin, const QPointF &point) { auto distance = qSqrt(point.x()*point.x() + point.y()*point.y()); auto radianAngle = qAtan2(point.x(), point.y()); auto azimuth = qRadiansToDegrees(radianAngle < 0 ? radianAngle + 2*M_PI : radianAngle); return origin.atDistanceAndAzimuth(distance, azimuth); } 


рдФрдкрдЪрд╛рд░рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рдпрд╣ рдЕрд╕рдВрднрд╡ рд╣реИ, рд╣рдорд╛рд░реЗ "рдкрд┐рдХреНрд╕реЗрд▓" рдФрд░ "рдореАрдЯрд░" рдкреНрд░рдХреНрд╖реЗрдкрд╡рдХреНрд░ рд╕рдорд╛рди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди рдпрд╣ рдореБрдЭреЗ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рджреЗрдЦрдиреЗ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕реНрд╡рд╛рджрд┐рд╖реНрдЯ рд▓рдЧ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдХреНрдпрд╛ рд╣реЛрдЧрд╛ (рдпрд╛ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╡рд┐рдорд╛рди рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЙрдбрд╝рд╛рди рдирд╣реАрдВ рднрд░рддрд╛ рд╣реИ) рдЬрдм рд╡рд╣ рдЕрдЧрд▓реА рдмрд╛рд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдЧрд╛ред рдкреНрд░рдХреНрд╖реЗрдкрд╡рдХреНрд░ рдХреЛ рдЕрдВрддрд┐рдо рд░реВрдк рджреЗрдиреЗ рдХреЗ рдмрд╛рдж (рдпрд╣ рдкрд┐рдХреНрд╕реЗрд▓ рдПрдХ рд╕реЗ рд░рдВрдЧ рдФрд░ рдкрд╛рд░рджрд░реНрд╢рд┐рддрд╛ рдореЗрдВ рдереЛрдбрд╝рд╛ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдереИрддрд┐рдХ рдЯреВрдЯреА рд╣реБрдИ рд░реЗрдЦрд╛рдПрдВ рдирдХреНрд╢реЗ рдкрд░ рдмрд╣реБрдд рдЪрд┐рдХрдиреА рдирд╣реАрдВ рджрд┐рдЦрддреА рд╣реИрдВ)ред

рдЫрд╡рд┐

рд╕реНрд░реЛрдд рдпрд╣рд╛рдБ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ , рд╕рдВрдХрд▓рди рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ Qt 5.11.2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред

рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рдЕрдкрдиреЗ рд╕рдВрдкрд╛рджрдХ рдХреЛ рдкреНрд░рдХреНрд╖реЗрдкрд╡рдХреНрд░ рдХреЗ рд╕рдВрджрд░реНрдн рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдЦрд╛рдПрдВрдЧреЗ, рд╕рд╛рде рд╣реА рд╕рд╛рде рд╡рд┐рдорд╛рдиреЛрдВ рдХреА рдЖрд╡рд╛рдЬрд╛рд╣реА рдХреЗ рдЕрдиреБрдХрд░рдг рдХреЗ рд▓рд┐рдП рдореМрдЬреВрджрд╛ рдкрдЯрд░рд┐рдпреЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ / рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рд╕рд┐рдЦрд╛рдПрдВрдЧреЗред

Source: https://habr.com/ru/post/hi433828/


All Articles