private Rotation3 correction_; // correction rotation to be done public PolarCorrectedAlignment(Vect3 newEquAxis, Vect3 prevEquAxis, double altOffset, Rotation3 prevRotationToStand, double equAngle0, double equAngleFactor, AlignStar[] stars) { equAxis_ = newEquAxis; altOffset_ = altOffset; equAngleFactor_ = equAngleFactor; // calculate RotationToStand for equatorial angle = 0 prevRotationToStand = prevRotationToStand * new Rotation3(-equAngle0 * equAngleFactor_, prevEquAxis); // convert coordinates of pole to scope coordinates Vect3 oldScopePoleAxis = prevRotationToStand.Apply(prevEquAxis); Vect3 newScopePoleAxis = prevRotationToStand.Apply(equAxis_); // correct first altitude, then correct azimuth correction_ = new Rotation3(newScopePoleAxis.Alt - oldScopePoleAxis.Alt, new Vect3(newScopePoleAxis.Azm + Math.PI / 2, 0)); correction_ = new Rotation3(newScopePoleAxis.Azm - oldScopePoleAxis.Azm, new Vect3(0, 0, -1)) * correction_; rotationToStand_ = correction_.Conj * prevRotationToStand; if (stars != null && stars.Length > 0) { stars_ = new AlignStar[stars.Length]; for (int i = 0; i < stars.Length; ++i) { if (stars[i] != null) { PairA newScope = DoHorz2Scope((PairA)stars[i].Horz, stars[i].EquAngle); stars_[i] = new AlignStar(stars[i].Name, stars[i].Horz, newScope, stars[i].EquAngle); } } } }
public override bool CorrectOffsets(AlignStar star) { if (star == null) { return(false); } ForceAlignment(); PairA scopeOld = Horz2Scope((PairA)star.Horz, star.EquAngle); double deltaAlt = star.Scope.Alt - scopeOld.Alt, deltaAzm = star.Scope.Azm - scopeOld.Azm; altOffset_ += deltaAlt; rotationToStand_ = new Rotation3(-deltaAzm, new Vect3(0, 0, 1)) * rotationToStand_; //PairA scopeNew = Horz2Scope((PairA)star.Horz, star.EquAngle); foreach (AlignStar s in stars_) { if (s != null) { //scopeNew = Horz2Scope((PairA)s.Horz, s.EquAngle); s.Scope = s.Scope.Offset(+deltaAzm, +deltaAlt); } } return(true); }
public override void ForceAlignment() { if (!alignmentDone_) { if (stars_[0] == null || stars_[1] == null) { throw new ApplicationException("No alignment stars"); } Vect3 star1horz_corrected = new Rotation3(stars_[1].EquAngle - stars_[0].EquAngle, equAxis_).Apply(stars_[1].Horz); Align(stars_[0].Horz, stars_[0].Scope, star1horz_corrected, stars_[1].Scope, precesions_, out altOffset_, out rotationToStand_, out quality_); alignmentDone_ = true; } }
// deep cloning private TwoStarsAlignment(Vect3 equAxis, AlignStar[] stars, bool alignmentDone, double altOffset, Rotation3 rotationToStand, double quality, Precisions precesions) { equAxis_ = equAxis; for (int i = 0; i < stars.Length; ++i) { if (stars[i] != null) { stars_[i] = (AlignStar)stars[i].Clone(); } } alignmentDone_ = alignmentDone; altOffset_ = altOffset; rotationToStand_ = rotationToStand; quality_ = quality; precesions_ = precesions; }
private void AlignStatic() { double altOffset1; Rotation3 rotationToStand1; double quality1; TwoStarsAlignment.Align(stars_[2].Horz, stars_[2].Scope, stars_[3].Horz, stars_[3].Scope, precesions_, out altOffset1, out rotationToStand1, out quality1); Rotation3 eqRotation = rotationToStand_.Conj * rotationToStand1; // actual equatorial rotation equAxis_ = eqRotation.Axis; equHorzDiff_ = eqRotation.Angle; // Generally, it isn't equal to equScopeDiff_. It depends on platform accuracy. altOffset_ = (altOffset_ + altOffset1) / 2; // average offset if (quality_ < quality1) { quality_ = quality1; // maximal quality } iterationCnt_ = 0; }
private PolarCorrectedAlignment(Vect3 equAxis, AlignStar[] stars, double altOffset, Rotation3 rotationToStand, double equAngleFactor, Rotation3 correction) { equAxis_ = equAxis; if (stars != null && stars.Length > 0) { stars_ = new AlignStar[stars.Length]; for (int i = 0; i < stars.Length; ++i) { if (stars[i] != null) { stars_[i] = (AlignStar)stars[i].Clone(); } } } altOffset_ = altOffset; rotationToStand_ = rotationToStand; equAngleFactor_ = equAngleFactor; correction_ = correction; }
// deep cloning private FourStarsAlignment(Vect3 equAxis, AlignStar[] stars, Rotation3 rotationToStand, double altOffset, double equHorzDiff, double quality, Precisions precesions, int iterationCnt, bool alignmentDone) { if (stars.Length < 4 || stars.Length > stars_.Length) { throw new ApplicationException("too few alignment stars"); } // check equatorial angles: 1) should be within limits for stars 0,1, 2) should be within limits for stars 2,3, and 3) should be different for (0,1) and (2,3) star pairs if (Math.Abs(stars[0].EquAngle - stars[1].EquAngle) > precesions.iterEquAngleDiff_ || Math.Abs(stars[2].EquAngle - stars[3].EquAngle) > precesions.iterEquAngleDiff_ || stars[0].EquAngle == stars[2].EquAngle) { throw new ApplicationException("bad data for 4-stars alignment"); } // check equatorial angles: 1) should be same for stars 0 and 1, 2) should be same for stars 2 and 3, and 3) should be different for (0,1) and (2,3) star pairs //if (stars[0].EquAngle != stars[1].EquAngle || stars[2].EquAngle != stars[3].EquAngle || stars[0].EquAngle == stars[2].EquAngle) // throw new ApplicationException("bad data for 4-stars alignment"); equAxis_ = equAxis; for (int i = 0; i < stars.Length; ++i) { if (stars[i] != null) { stars_[i] = (AlignStar)stars[i].Clone(); } } rotationToStand_ = rotationToStand; altOffset_ = altOffset; equScopeDiff_ = stars_[2].EquAngle - stars_[0].EquAngle; equHorzDiff_ = equHorzDiff; quality_ = quality; precesions_ = precesions; iterationCnt_ = iterationCnt; alignmentDone_ = alignmentDone; }
private void AlignDynamic() { double equAngleFactor = 1; for (int i = 0; i < precesions_.iterCnt_; ++i) { Vect3 star1horz_corrected = new Rotation3((stars_[1].EquAngle - stars_[0].EquAngle) * equAngleFactor, equAxis_).Apply(stars_[1].Horz); Vect3 star3horz_corrected = new Rotation3((stars_[3].EquAngle - stars_[2].EquAngle) * equAngleFactor, equAxis_).Apply(stars_[3].Horz); double altOffset0; Rotation3 rotationToStand0; double quality0; TwoStarsAlignment.Align(stars_[0].Horz, stars_[0].Scope, star1horz_corrected, stars_[1].Scope, precesions_, out altOffset0, out rotationToStand0, out quality0); double altOffset1; Rotation3 rotationToStand1; double quality1; TwoStarsAlignment.Align(stars_[2].Horz, stars_[2].Scope, star3horz_corrected, stars_[3].Scope, precesions_, out altOffset1, out rotationToStand1, out quality1); Rotation3 eqRotation = rotationToStand0.Conj * rotationToStand1; // actual equatorial rotation Vect3 equAxisNew = eqRotation.Axis; double diff = Vect3.VMul(equAxis_, equAxisNew).Abs; equAxis_ = equAxisNew; if (diff < precesions_.iterEquAxisDiff_) { equHorzDiff_ = eqRotation.Angle; // Generally, it isn't equal to equScopeDiff_. It depends on platform accuracy. rotationToStand_ = rotationToStand0; altOffset_ = (altOffset0 + altOffset1) / 2; // average offset quality_ = (quality0 > quality1) ? quality0 : quality1; // maximal quality iterationCnt_ = i + 1; return; } equAngleFactor = eqRotation.Angle / equScopeDiff_; } throw new ApplicationException("too many iterations"); }
public static void Align(Vect3 horz0, PairA scope0, Vect3 horz1, PairA scope1, Precisions precesions, out double altOffset, out Rotation3 rotationToStand, out double quality) { altOffset = CalcAltOffset(horz0, scope0, horz1, scope1); Vect3 s0 = new Vect3(scope0.Offset(0, -altOffset)); Vect3 s1 = new Vect3(scope1.Offset(0, -altOffset)); double abs; Vect3 n0 = horz0 - s0; abs = n0.Abs; if (abs < precesions.rotation_) { double angle = CalcRotationAngle(s0, horz1, s1); if (angle == 0 || angle == Math.PI) { throw new ApplicationException("Error7"); } quality = -1; rotationToStand = new Rotation3(angle, s0); return; } n0 /= abs; Vect3 n1 = horz1 - s1; abs = n1.Abs; if (abs < precesions.rotation_) { double angle = CalcRotationAngle(s1, horz0, s0); if (angle == 0 || angle == Math.PI) { throw new ApplicationException("Error8"); } quality = -2; rotationToStand = new Rotation3(angle, s1); return; } n1 /= abs; // axis Vect3 axis = Vect3.VMul(n0, n1); abs = axis.Abs; if (abs < precesions.axis_) { throw new ApplicationException("Error4"); } axis /= abs; double angle0 = CalcRotationAngle(axis, horz0, s0); if (angle0 == 0 || angle0 == Math.PI) { throw new ApplicationException("Error5"); } double angle1 = CalcRotationAngle(axis, horz1, s1); if (angle1 == 0 || angle1 == Math.PI) { throw new ApplicationException("Error6"); } quality = Math.Abs(angle0 - angle1); rotationToStand = new Rotation3((angle0 + angle1) / 2, axis); }