void CalcRepl::write() { if (outStack.empty() && midStack.empty()) { // Nothing } else { CalcData result = finishByData(); // If not NaN, find near value if (result == result) { CalcNearData nearresult = fnear(result); // Find x ~= result const auto found1 = NearValue.find(nearresult); if (found1 != NearValue.end()) { (*out)<<" ~ "<<found1->second<<endl; } else { // Find x ~= -result const auto found2 = NearValue.find(-nearresult); if (found2 != NearValue.end()) { (*out)<<" ~ "<<"- ("<<found2->second<<")"<<endl; } else { // Find any ~= result if (nearresult != (CalcNearData)result) { (*out)<<" ~ "<<nearresult<<endl; } } } } (*out)<<" = "<<result<<endl; (*out).flush(); } }
void Orbit::initAP(double sgp, FGDoubleVector &apogee, FGDoubleVector &perigee) { // we need eccentricity, semomajor axis, and angle. All are pretty easy to get // when you know the apogee, perigee, and a focus. // sanity check: The apogee and perigee have to be in line with the focus (0,0). // we'll just check the angles and their difference double angleDiff = FGDoubleGeometry::angleDiff(apogee.getAngle(), perigee.getAngle()); angleDiff = fabs(angleDiff); if ( !fnear(angleDiff, PI, 0.01) ) { // not close enough to opposition. m_bValid = false; return; } // pretty straight forward, and we'll need them in a minute. m_apogee = apogee.getLength(); m_perigee = perigee.getLength(); // the semimajor axis is just half the distance from perigee to apogee. m_a = (m_apogee + m_perigee)/2.0; // w is the angle from f1 to apogee. m_w = apogee.getAngle(); // and e is defined as (a-p)/(a+p) where a and p are apogee and perigee distances m_e = (m_apogee-m_perigee)/(m_apogee+m_perigee); // we now have the criticals init(sgp, m_e, m_a, m_w); }
static inline bool ffar(const float x, const float y) { return !fnear(x,y); }
void MainWindow::doRun(const QString &value) { try { // Do calculation calc.parse(value.toStdString()); const OPParser::CalcData resultC = calc.finishByData(); const OPParser::CalcData resultCNear = fnear(resultC); std::string resultS = value.toStdString(); // If not NaN, find near value if (resultCNear == resultCNear) { // Find x ~= result const auto found1 = OPParser::NearValue.find(resultCNear); if (found1 != OPParser::NearValue.end()) { resultS += "=" + found1->second; } else { // Find x ~= -result const auto found2 = OPParser::NearValue.find(-resultCNear); if (found2 != OPParser::NearValue.end()) { resultS += "=-(" + found2->second + ")"; } } } { // Format result as string std::ostringstream oss; oss << resultCNear; auto floatS = oss.str(); // Format exp auto ePos = floatS.find("e"); if (ePos != std::string::npos) { floatS.replace(ePos, 1, " e^"); } resultS += "=" + floatS; } // Generate MML mml.parse(resultS); const OPParser::MMLData resultM = mml.finishByData(); // Print ui->statusBar->showMessage(QString(std::to_string(resultC).c_str())); ui->frame->setContent(QString(resultM.c_str())); // Scale the font size to fit in ui->frame->setBaseFontPointSize(16); while ( ( ui->frame->getSize().width() > ui->frame->width() || ui->frame->getSize().height() > ui->frame->height() ) && ui->frame->baseFontPointSize() > 8 ) { ui->frame->setBaseFontPointSize(ui->frame->baseFontPointSize() - 1); } } catch (const OPParser::opparser_error &e) { ui->statusBar->showMessage(QString(e.what())); calc.init(); mml.init(); } }