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);
                    }
                }
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
 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;
     }
 }
Beispiel #4
0
 // 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");
        }
Beispiel #9
0
        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);
        }