void WallsUnits::applyHeightCorrections(ULength& dist, UAngle& fsInc, UAngle& bsInc, ULength ih, ULength th) const { if (inch.isNonzero() || ih.isNonzero() || th.isNonzero()) { UAngle inc = avgInc(fsInc + incv, bsInc + incvb); if (inc.isValid() && !isVertical(inc)) { // horizontal offset before height correction ULength ne = ucos(inc) * (dist + incd); // vertical offset before height correction ULength u = usin(inc) * (dist + incd); u += inch; if (ih.isValid()) u += ih; if (th.isValid()) u -= th; // adjust fsInc/bsInc so that their new avg // is the corrected inclination UAngle dinc = uatan2(u, ne) - inc; fsInc += dinc; bsInc += (typevb_corrected ? dinc : -dinc); dist = usqrt(usq(ne) + usq(u)) - incd; } } }
UAngle WallsUnits::avgInc(UAngle fsInc, UAngle bsInc) const { if (!typevb_corrected) { bsInc = -bsInc; } if (!fsInc.isValid()) { return bsInc; } else if (!bsInc.isValid()) { return fsInc; } return (fsInc + bsInc) * 0.5; }
void testInstance(ULength instY, ULength targetY, ULength fromY, ULength toY, ULength horizDist, ULength inch, QList<TapingMethodMeasurement> tape) { WallsUnits units; units.setInch(inch); units.setIncd(ULength(1, Length::Inches)); units.setIncs(ULength(1, Length::Inches)); units.setIncv(UAngle(2, Angle::Degrees)); units.setTape(tape); INFO( "instY: " << instY ); INFO( "targetY: " << targetY ); INFO( "fromY: " << fromY ); INFO( "toY: " << toY ); INFO( "horizDist: " << horizDist ); INFO( "inch: " << inch ); ULength tapeFromY = tape[0] == TapingMethodMeasurement::InstrumentHeight ? instY : fromY; ULength tapeToY = tape[1] == TapingMethodMeasurement::TargetHeight ? targetY : toY; Vector vector; vector.setDistance(usqrt(usq(horizDist) + usq(tapeToY - tapeFromY)) - units.incd()); vector.setFrontAzimuth(UAngle(0, Angle::Degrees) - units.inca()); if (horizDist.isNonzero() && targetY != instY) { vector.setFrontInclination(uatan((targetY - instY) / horizDist) - units.incv()); } vector.setInstHeight(instY - fromY - units.incs()); vector.setTargetHeight(targetY - toY - units.incs()); vector.setUnits(units); ULength expectedDist = usqrt(usq(toY + inch - fromY) + usq(horizDist)); UAngle expectedInc = uatan2((toY + inch - fromY), horizDist); ULength instHeightAboveTape = instY - tapeFromY; ULength targetHeightAboveTape = targetY - tapeToY; bool isDiveShot = tape[0] == TapingMethodMeasurement::Station && tape[1] == TapingMethodMeasurement::Station && (!vector.frontInclination().isValid() || vector.frontInclination().isZero()); if (!isDiveShot && uabs(instHeightAboveTape - targetHeightAboveTape) > vector.distance()) { CHECK_THROWS( vector.applyHeightCorrections() ); } else { vector.applyHeightCorrections(); CHECK( (vector.distance() + units.incd()).get(Length::Meters) == Approx( expectedDist.get(Length::Meters) ) ); CHECK( (vector.frontInclination() + units.incv()).get(Angle::Degrees) == Approx( expectedInc.get(Angle::Degrees) ) ); } }
bool WallsUnits::isVertical(UAngle angle) { return fabs(fabs(angle.get(Angle::degrees())) - 90.0) < 1e-4; }