-
Sponsor
Sponsor KDE/kstars
- Notifications
- Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
19 changed files
with
1,567 additions
and
1,296 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,10 @@ | ||
ADD_EXECUTABLE( test_poleaxis test_poleaxis.cpp ) | ||
TARGET_LINK_LIBRARIES( test_poleaxis ${TEST_LIBRARIES}) | ||
ADD_TEST( NAME TestPoleAxis COMMAND test_poleaxis ) | ||
ADD_EXECUTABLE( test_polaralign test_polaralign.cpp ) | ||
TARGET_LINK_LIBRARIES( test_polaralign ${TEST_LIBRARIES}) | ||
ADD_TEST( NAME TestPolarAlign COMMAND test_polaralign ) | ||
ADD_CUSTOM_COMMAND( TARGET test_polaralign POST_BUILD | ||
COMMAND ${CMAKE_COMMAND} -E copy | ||
${CMAKE_CURRENT_SOURCE_DIR}/../fitsviewer/ngc4535-autofocus1.fits | ||
${CMAKE_CURRENT_BINARY_DIR}/ngc4535-autofocus1.fits) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/*************************************************************************** | ||
test_poleaxis.cpp - KStars Planetarium | ||
------------------- | ||
begin : Tue 27 Sep 2016 20:54:28 CDT | ||
copyright : (c) 2016 by Akarsh Simha | ||
email : akarsh.simha@kdemail.net | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
/* Project Includes */ | ||
#include "test_poleaxis.h" | ||
#include "ksnumbers.h" | ||
#include "time/kstarsdatetime.h" | ||
#include "auxiliary/dms.h" | ||
#include "Options.h" | ||
#include <libnova/libnova.h> | ||
|
||
TestPoleAxis::TestPoleAxis() : QObject() | ||
{ | ||
} | ||
|
||
TestPoleAxis::~TestPoleAxis() | ||
{ | ||
} | ||
|
||
void TestPoleAxis::compare(PoleAxis::V3 v, double x, double y, double z) | ||
{ | ||
QVERIFY2(std::fabs(v.x() - x) < 0.00001, | ||
qPrintable(QString("dc.x %1, x %2 error %3").arg(v.x()).arg(x).arg(((v.x() - x) * 3600.0), 6, 'f', 1))); | ||
QVERIFY2(std::fabs(v.y() - y) < 0.00001, | ||
qPrintable(QString("dc.y %1, y %2 error %3").arg(v.y()).arg(y).arg(((v.y() - y) * 3600.0), 6, 'f', 1))); | ||
QVERIFY2(std::fabs(v.z() - z) < 0.00001, | ||
qPrintable(QString("dc.z %1, z %2 error %3").arg(v.z()).arg(z).arg(((v.z() - z) * 3600.0), 6, 'f', 1))); | ||
} | ||
|
||
void TestPoleAxis::compare(double a, double e, QString msg) | ||
{ | ||
QVERIFY2(std::fabs(a - e) < 0.0003, | ||
qPrintable(QString("%1: actual %2, expected %3 error %4").arg(msg).arg(a).arg(e).arg(((a - e) * 3600.0), 6, 'f', 1))); | ||
} | ||
|
||
|
||
void TestPoleAxis::testDirCos_data() | ||
{ | ||
QTest::addColumn<double>("Ha"); | ||
QTest::addColumn<double>("Dec"); | ||
QTest::addColumn<double>("X"); | ||
QTest::addColumn<double>("Y"); | ||
QTest::addColumn<double>("Z"); | ||
|
||
QTest::newRow("HaDec0") << 0.0 << 0.0 << 1.0 << 0.0 << 0.0; | ||
QTest::newRow("Ha0Dec45") << 0.0 << 45.0 << 0.707107 << 0.0 << 0.707107; | ||
QTest::newRow("Ha6Dec45") << 6.0 << 45.0 << 0.0 << 0.707107 << 0.707107; | ||
QTest::newRow("Ha-6Dec45") << -6.0 << 45.0 << 0.0 << -0.707107 << 0.707107; | ||
QTest::newRow("at Pole") << 0.0 << 90.0 << 0.0 << 0.0 << 1.0; | ||
QTest::newRow("near S Pole") << -3.0 << -85.0 << 0.0616284 << -0.0616284 << -0.996195; | ||
} | ||
|
||
void TestPoleAxis::testDirCos() | ||
{ | ||
dms h; | ||
dms d; | ||
QFETCH(double, Ha); | ||
QFETCH(double, Dec); | ||
h.setH(Ha); | ||
d.setD(Dec); | ||
|
||
|
||
PoleAxis::V3 dc; | ||
dc = PoleAxis::dirCos(h, d); | ||
|
||
|
||
QFETCH(double, X); | ||
QFETCH(double, Y); | ||
QFETCH(double, Z); | ||
|
||
compare(dc, X, Y, Z); | ||
|
||
SkyPoint sp(Ha, Dec); | ||
dc = PoleAxis::dirCos(sp); | ||
compare(dc.length(), 1.0, "length"); | ||
compare(dc, X, Y, Z); | ||
} | ||
|
||
void TestPoleAxis::testPriSec_data() | ||
{ | ||
testDirCos_data(); | ||
} | ||
|
||
void TestPoleAxis::testPriSec() | ||
{ | ||
QFETCH(double, Ha); | ||
QFETCH(double, Dec); | ||
QFETCH(double, X); | ||
QFETCH(double, Y); | ||
QFETCH(double, Z); | ||
PoleAxis::V3 dc(X, Y, Z); | ||
dms p = PoleAxis::primary(dc); | ||
compare(p.HoursHa(), Ha, "Ha"); | ||
compare(PoleAxis::secondary(dc).Degrees(), Dec, "Dec"); | ||
} | ||
|
||
|
||
void TestPoleAxis::testPoleAxis_data() | ||
{ | ||
QTest::addColumn<double>("Ha1"); | ||
QTest::addColumn<double>("Dec1"); | ||
QTest::addColumn<double>("Ha2"); | ||
QTest::addColumn<double>("Dec2"); | ||
QTest::addColumn<double>("Ha3"); | ||
QTest::addColumn<double>("Dec3"); | ||
QTest::addColumn<double>("X"); | ||
QTest::addColumn<double>("Y"); | ||
QTest::addColumn<double>("Z"); | ||
|
||
QTest::newRow("Ha-606Dec0") << -6.0 << 0.0 << 0.0 << 0.0 << 6.0 << 0.0 << 0.0 << 0.0 << 1.0; | ||
QTest::newRow("Ha20-2Dec89") << 2.0 << 89.0 << 0.0 << 89.0 << -2.0 << 89.0 << 0.0 << 0.0 << -1.0; | ||
QTest::newRow("Ha0-22Dec89v") << 0.0 << 89.0 << -2.0 << 89.1 << 2.0 << 88.9 << -0.0006 << -0.003386 << -0.99999; | ||
QTest::newRow("Ha2-20Dec-89") << 2.0 << -89.0 << -2.0 << -89.0 << 0.0 << -89.0 << 0.0 << 0.0 << 1.0; | ||
QTest::newRow("Ha20-2Dec89") << 2.0 << 89.0 << 0.0 << 89.0 << -2.0 << 88.0 << 0.05633683 << 0.0150954 << 0.998298; | ||
// failure cases, 2 or more points the same should ruturn a null matrix | ||
QTest::newRow("Ha000Dec0") << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0; | ||
QTest::newRow("Ha100Dec0") << 1.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0; | ||
QTest::newRow("Ha110Dec0") << 1.0 << 0.0 << 1.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0 << 0.0; | ||
QTest::newRow("Ha011Dec0") << 0.0 << 0.0 << 1.0 << 0.0 << 1.0 << 0.0 << 0.0 << 0.0 << 0.0; | ||
} | ||
|
||
void TestPoleAxis::testPoleAxis() | ||
{ | ||
QFETCH(double, Ha1); | ||
QFETCH(double, Dec1); | ||
QFETCH(double, Ha2); | ||
QFETCH(double, Dec2); | ||
QFETCH(double, Ha3); | ||
QFETCH(double, Dec3); | ||
|
||
QFETCH(double, X); | ||
QFETCH(double, Y); | ||
QFETCH(double, Z); | ||
|
||
SkyPoint p1(Ha1, Dec1); | ||
SkyPoint p2(Ha2, Dec2); | ||
SkyPoint p3(Ha3, Dec3); | ||
|
||
|
||
PoleAxis::V3 pa = PoleAxis::poleAxis(p1, p2, p3); | ||
|
||
compare(pa.x(), X, "X"); | ||
compare(pa.y(), Y, "Y"); | ||
compare(pa.z(), Z, "Z"); | ||
} | ||
|
||
QTEST_GUILESS_MAIN(TestPoleAxis) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/*************************************************************************** | ||
test_poleaxis.h - KStars Planetarium | ||
------------------- | ||
begin : Tue 27 Sep 2016 20:51:21 CDT | ||
copyright : (c) 2020 by Chris Rowland | ||
email : | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#ifndef TEST_POLEAXIS_H | ||
#define TEST_POLEAXIS_H | ||
|
||
#include <QtTest/QtTest> | ||
#include <QDebug> | ||
#include <QString> | ||
|
||
#define UNIT_TEST | ||
|
||
#include "../../kstars/ekos/align/poleaxis.h" | ||
|
||
/** | ||
* @class TestPoleAxis | ||
* @short Tests for some polar align operations | ||
* @author Chris Rowland | ||
*/ | ||
|
||
class TestPoleAxis : public QObject | ||
{ | ||
Q_OBJECT | ||
|
||
public: | ||
TestPoleAxis(); | ||
~TestPoleAxis() override; | ||
|
||
private slots: | ||
void testDirCos_data(); | ||
void testDirCos(); | ||
void testPriSec_data(); | ||
void testPriSec(); | ||
void testPoleAxis_data(); | ||
void testPoleAxis(); | ||
|
||
private: | ||
void compare(PoleAxis::V3 v, double x, double y, double z); | ||
void compare(double a, double e, QString msg = ""); | ||
void compare(float a, double e, QString msg = "") | ||
{ | ||
compare (static_cast<double>(a), e, msg); | ||
} | ||
|
||
}; | ||
|
||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,76 +1,115 @@ | ||
/* polaralign.h determines the mount polar axis position | ||
Copyright (C) 2020 Chris Rowland <chris.rowland@cherryfield.me.uk> | ||
/* PolarAlign class. | ||
Copyright (C) 2021 Hy Murveit | ||
This application is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU General Public | ||
License as published by the Free Software Foundation; either | ||
version 2 of the License, or (at your option) any later version. | ||
*/ | ||
|
||
#ifndef POLARALIGN_H | ||
#define POLARALIGN_H | ||
#pragma once | ||
|
||
#include <QVector3D> | ||
#include <dms.h> | ||
#include <skypoint.h> | ||
|
||
/** | ||
*@class PolarAlign | ||
*@short PolarAlign class handles determining the mount Ha axis position given three positions taken with the same mount declination. | ||
* | ||
*@author Chris Rowland | ||
*@version 1.0 | ||
*/ | ||
class FITSData; | ||
class TestPolarAlign; | ||
|
||
/********************************************************************* | ||
Polar alignment support class. Note, the telescope can be pointing anywhere. | ||
It doesn't need to point at the pole. | ||
Use this class as follows: | ||
1) Construct with the geo information. | ||
PolarAlign polarAlign(geoLocation); | ||
2) Start the polar align procedure. Capture, solve and add wcs from the | ||
solve to the FITSData image. Then: | ||
polarAlign.addPoint(image); | ||
3) Rotate the mount in RA ~30 degrees (could be less or more) east (or west) | ||
and capture, solve and add wcs from the solve to the the new image. Then: | ||
polarAlign.addPoint(image); | ||
4) Rotate the mount in RA another ~30 degrees east (or west) | ||
and capture, solve and add wcs from the solve to the the new image. Then: | ||
polarAlign.addPoint(image); | ||
5) Find the mount's axis of rotation as follows: | ||
if (!polarAlign.findAxis()) | ||
error(); | ||
6) Compute the azimuth and altitude offset for the mount. | ||
double altitudeError = axisAlt - latitudeDegrees; | ||
double azimuthError = axisAz - 0; | ||
7) Compute the overall error | ||
dms polarError(hypot(altitudeError, azimuthError)); | ||
8) Compute a target correction | ||
int correctedX, correctedY; | ||
if (!polarAlign.findCorrectedPixel( | ||
imageData, x, y, altitudeError, azimuthError, &correctedX, &correctedY)) | ||
error(); | ||
9) The user should use the GEM azimuth and altitude adjustments to move the | ||
object at position x,y in the image to position correctedX, correctedY. | ||
*********************************************************************/ | ||
|
||
class PolarAlign | ||
{ | ||
public: | ||
/// | ||
/// \brief dirCos converts primary and secondary angles to a directional cosine | ||
/// \param primary angle, can be Ra, Ha, Azimuth or the corresponding axis values | ||
/// \param secondary angle, can be Dec, Altitude. 90 deg is the pole | ||
/// \return QVector3D containing the directional cosine. | ||
static QVector3D dirCos(const dms primary, const dms secondary); | ||
|
||
/// | ||
/// \brief dirCos converts a SkyPoint to a directional cosine | ||
/// \param sp SkyPoint with the position | ||
/// \return QVector3D containing the directional cosine. | ||
/// | ||
static QVector3D dirCos(const SkyPoint sp); | ||
|
||
/// | ||
/// \brief primary returns the primary dms value in the directional cosine | ||
/// \param dirCos | ||
/// \return primary angle, Ra, Ha, Azimuth etc. | ||
/// | ||
static dms primary(QVector3D dirCos); | ||
|
||
/// | ||
/// \brief secondary returns the secondary dms angle in the directional cosine | ||
/// \param dirCos | ||
/// \return | ||
/// | ||
static dms secondary(QVector3D dirCos); | ||
|
||
/// | ||
/// \brief skyPoint returns a skypoint derived from the directional cosine vector | ||
/// \param dc | ||
/// \return | ||
/// | ||
static SkyPoint skyPoint(QVector3D dc); | ||
|
||
/// | ||
/// \brief poleAxis returns the pole axis vector given three SkyPoints with the same mount declination | ||
/// \param p1 | ||
/// \param p2 | ||
/// \param p3 | ||
/// \return vector giving the direction of the pole. The rotation between the three points determines which pole | ||
/// the other pole can be determined either by reversing the sign of the declination and adding 12 hrs to the Ha or | ||
/// by negating the vector | ||
/// | ||
static QVector3D poleAxis(SkyPoint p1, SkyPoint p2, SkyPoint p3); | ||
public: | ||
|
||
}; | ||
// The polealignment scheme requires the GeoLocation to operate properly. | ||
// Certain aspects can be tested without it. | ||
PolarAlign(const GeoLocation *geo = nullptr); | ||
|
||
// Add a sample point. | ||
bool addPoint(FITSData *image); | ||
|
||
// Finds the mount's axis of rotation. Three points must have been added. | ||
// Returns false if the axis can't be found. | ||
bool findAxis(); | ||
|
||
// Returns the image coordinate that pixel x,y should be moved to to correct | ||
// the mount's axis. Image is usually the 3rd PAA image. x,y are image coordinates. | ||
// 3 Points must have been added and findAxis() must have been called. | ||
// Uses the axis determined by findAxis(). Returns correctedX and correctedY, | ||
// the target position that the x,y pixel should move to. | ||
bool findCorrectedPixel(FITSData *image, const QPointF &pixel, | ||
QPointF *corrected, bool altOnly = false); | ||
|
||
// Returns the mount's azimuth and altitude error given the known geographic location | ||
// and the azimuth center and altitude center computed in findAxis(). | ||
void calculateAzAltError(double *azError, double *altError) const; | ||
|
||
#endif // POLARALIGN_H | ||
/// reset starts the process over, removing the points. | ||
void reset(); | ||
|
||
// Returns the mount's axis--for debugging. | ||
void getAxis(double *azAxis, double *altAxis) const; | ||
|
||
private: | ||
// Rotate the az/alt point. Used when assisting the user to correct a polar alignment error. | ||
// Input is the point to be rotated, Azimuth = azAltPoint.x(), Altitude = azAltPoint.y(). | ||
// azAltRotation: the rotation angles, which correspond to the error in polar alignment | ||
// that we would like to correct at the pole. azAltResult.x() is the rotated azimuth coordinate. | ||
// azAltResult.y() is the rotated altitude coordinate. | ||
void rotate(const QPointF &azAltPoint, const QPointF &azAltRotation, QPointF *azAltResult) const; | ||
|
||
// returns true in the northern hemisphere. | ||
// if no geo location available, defaults to northern. | ||
bool northernHemisphere() const; | ||
|
||
// These internal methods find the pixel with the desired azimuth and altitude. | ||
bool findAzAlt(FITSData *image, double azimuth, double altitude, QPointF *pixel) const; | ||
|
||
// Does the necessary processing so that azimuth and altitude values | ||
// can be retrieved for the x,y pixel in image. | ||
bool prepareAzAlt(FITSData *image, const QPointF &pixel, SkyPoint *point) const; | ||
|
||
// These three positions are used to estimate the polar alignment error. | ||
QVector<SkyPoint> points; | ||
QVector<KStarsDateTime> times; | ||
|
||
// The geographic location used to compute altitude and azimuth. | ||
const GeoLocation *geoLocation; | ||
|
||
// Values set by the last call to findAxis() that correspond to the mount's axis. | ||
double azimuthCenter { 0 }; | ||
double altitudeCenter { 0 }; | ||
|
||
friend TestPolarAlign; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* poleaxis.cpp determines the mount polar axis position | ||
Copyright (C) 2020 Chris Rowland <chris.rowland@cherryfield.me.uk> | ||
This application is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU General Public | ||
License as published by the Free Software Foundation; either | ||
version 2 of the License, or (at your option) any later version. | ||
*/ | ||
|
||
#include "poleaxis.h" | ||
|
||
#include <cmath> | ||
|
||
|
||
/****************************************************************** | ||
poleAxis(sp1, sp2, sp3) finds the mount's RA axis of rotation determined | ||
by three points sampled by fixing the mount's DEC and sampling a point | ||
a three different RA position. | ||
For each SkyPoint sp, it finds its corresponding x,y,z coordinates, | ||
which are points on a unit sphere. Those 3 coordinates define a plane. | ||
That plane intesects the sphere, and the intersection of a plane and a | ||
sphere is a circle. The center of that circle would be the axis of rotation | ||
defined by the origial 3 points. So, finding the normal to the plane, | ||
and pointing in that (normal) direction from the center of the sphere | ||
(the origin) gives the axis of rotation of the mount. | ||
poleAxis returns the normal. The way to interpret this vector | ||
is a unit vector (direction) in the x,y,z space. To convert this back to an | ||
angle useful for polar alignment, the ra and dec angles can be | ||
retrieved with the primary(V) and secondary(V) functions. | ||
These can then be turned into an altitude and azimuth angles using methods | ||
in the SkyPoint class. | ||
Further detail | ||
Definitions: SkyPoint sp contains an hour angle ha and declication dec, | ||
with the usual convention that dec=0 is the equator, dec=90 is the north pole | ||
about which the axis spins, and ha is the spin angle | ||
(positive is counter clockwise when looking north from the center of the sphere) | ||
where 0-degrees would be pointing "up", e.g. toward the zenith when | ||
looking at the north pole. The sphere has radius 1.0. | ||
dirCos(sp) will return a 3D vector V whose components x,y,z | ||
are 3D cartesean coordinate positions given these ha & dec angles | ||
for points on the surface of a unit sphere. | ||
The z direction points towards the north pole. | ||
The y direction points left when looking at the north pole | ||
The x direction points "up". | ||
primary(V) where V contains the above x,y,z coordinates, | ||
will return the ha angle pointing to V. | ||
secondary(V) where V contains the above x,y,z coordinates, | ||
will return the dec angle pointing to V. | ||
******************************************************************/ | ||
|
||
PoleAxis::V3 PoleAxis::V3::normal(const V3 &v1, const V3 &v2, const V3 &v3) | ||
{ | ||
// First subtract d21 = V2-V1; d31 = V3-V1 | ||
const V3 d21 = V3(v2.x() - v1.x(), v2.y() - v1.y(), v2.z() - v1.z()); | ||
const V3 d31 = V3(v3.x() - v2.x(), v3.y() - v2.y(), v3.z() - v2.z()); | ||
// Now take the cross-product of d21 and d31 | ||
const V3 cross = V3(d21.y() * d31.z() - d21.z() * d31.y(), | ||
d21.z() * d31.x() - d21.x() * d31.z(), | ||
d21.x() * d31.y() - d21.y() * d31.x()); | ||
// Finally normalize cross so that it is a unit vector. | ||
const double lenSq = cross.x() * cross.x() + cross.y() * cross.y() + cross.z() * cross.z(); | ||
if (lenSq == 0.0) return V3(); | ||
const double len = sqrt(lenSq); | ||
// Should we also fail if len < e.g. 5e-8 ?? | ||
return V3(cross.x() / len, cross.y() / len, cross.z() / len); | ||
} | ||
|
||
double PoleAxis::V3::length() | ||
{ | ||
return sqrt(X * X + Y * Y + Z * Z); | ||
} | ||
|
||
PoleAxis::V3 PoleAxis::dirCos(const dms primary, const dms secondary) | ||
{ | ||
return V3( | ||
static_cast<float>(secondary.cos() * primary.cos()), | ||
static_cast<float>(secondary.cos() * primary.sin()), | ||
static_cast<float>(secondary.sin())); | ||
} | ||
|
||
PoleAxis::V3 PoleAxis::dirCos(const SkyPoint sp) | ||
{ | ||
return dirCos(sp.ra(), sp.dec()); | ||
} | ||
|
||
dms PoleAxis::primary(V3 dirCos) | ||
{ | ||
dms p; | ||
p.setRadians(static_cast<double>(std::atan2(dirCos.y(), dirCos.x()))); | ||
return p; | ||
} | ||
|
||
dms PoleAxis::secondary(V3 dirCos) | ||
{ | ||
dms p; | ||
p.setRadians(static_cast<double>(std::asin(dirCos.z()))); | ||
return p; | ||
} | ||
|
||
SkyPoint PoleAxis::skyPoint(V3 dc) | ||
{ | ||
return SkyPoint(primary(dc), secondary(dc)); | ||
} | ||
|
||
PoleAxis::V3 PoleAxis::poleAxis(SkyPoint p1, SkyPoint p2, SkyPoint p3) | ||
{ | ||
// convert the three positions to vectors, these define the plane | ||
// of the Ha axis rotation | ||
V3 v1 = PoleAxis::dirCos(p1); | ||
V3 v2 = PoleAxis::dirCos(p2); | ||
V3 v3 = PoleAxis::dirCos(p3); | ||
|
||
// the Ha axis direction is the normal to the plane | ||
V3 p = V3::normal(v1, v2, v3); | ||
|
||
// p points to the north or south pole depending on the rotation of the points | ||
// the other pole position can be determined by reversing the sign of the Dec and | ||
// adding 12hrs to the Ha value. | ||
// if we want only the north then this would do it | ||
//if (p.z() < 0) | ||
// p = -p; | ||
return p; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* poleaxis.h determines the mount polar axis position | ||
Copyright (C) 2020 Chris Rowland <chris.rowland@cherryfield.me.uk> | ||
This application is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU General Public | ||
License as published by the Free Software Foundation; either | ||
version 2 of the License, or (at your option) any later version. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <dms.h> | ||
#include <skypoint.h> | ||
|
||
/** | ||
*@class PoleAxis | ||
*@short PoleAxis class handles determining the mount Ha axis position given three positions taken with the same mount declination. | ||
* | ||
*@author Chris Rowland | ||
*@version 1.0 | ||
*/ | ||
class PoleAxis | ||
{ | ||
public: | ||
// Like QVector3D but double precision. | ||
class V3 | ||
{ | ||
public: | ||
V3(double x, double y, double z) : X(x), Y(y), Z(z) {}; | ||
V3() : X(0.0), Y(0.0), Z(0.0) {}; | ||
double x() const | ||
{ | ||
return X; | ||
} | ||
double y() const | ||
{ | ||
return Y; | ||
} | ||
double z() const | ||
{ | ||
return Z; | ||
} | ||
static V3 normal(const V3 &v1, const V3 &v2, const V3 &v3); | ||
double length(); | ||
private: | ||
double X, Y, Z; | ||
}; | ||
|
||
/// | ||
/// \brief dirCos converts primary and secondary angles to a directional cosine | ||
/// \param primary angle, can be Ra, Ha, Azimuth or the corresponding axis values | ||
/// \param secondary angle, can be Dec, Altitude. 90 deg is the pole | ||
/// \return V3 containing the directional cosine. | ||
static V3 dirCos(const dms primary, const dms secondary); | ||
|
||
/// | ||
/// \brief dirCos converts a SkyPoint to a directional cosine | ||
/// \param sp SkyPoint with the position | ||
/// \return V3 containing the directional cosine. | ||
/// | ||
static V3 dirCos(const SkyPoint sp); | ||
|
||
/// | ||
/// \brief primary returns the primary dms value in the directional cosine | ||
/// \param dirCos | ||
/// \return primary angle, Ra, Ha, Azimuth etc. | ||
/// | ||
static dms primary(V3 dirCos); | ||
|
||
/// | ||
/// \brief secondary returns the secondary dms angle in the directional cosine | ||
/// \param dirCos | ||
/// \return | ||
/// | ||
static dms secondary(V3 dirCos); | ||
|
||
/// | ||
/// \brief skyPoint returns a skypoint derived from the directional cosine vector | ||
/// \param dc | ||
/// \return | ||
/// | ||
static SkyPoint skyPoint(V3 dc); | ||
|
||
/// | ||
/// \brief poleAxis returns the pole axis vector given three SkyPoints with the same mount declination | ||
/// \param p1 | ||
/// \param p2 | ||
/// \param p3 | ||
/// \return vector giving the direction of the pole. The rotation between the three points determines which pole | ||
/// the other pole can be determined either by reversing the sign of the declination and adding 12 hrs to the Ha or | ||
/// by negating the vector | ||
/// | ||
static V3 poleAxis(SkyPoint p1, SkyPoint p2, SkyPoint p3); | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters