VSOP was developed and is maintained (updated with the latest data) by the scientists at the Bureau des Longitudes in Paris.
VSOP87, computed the positions of the planets directly at any moment, as well as their orbital elements with improved accuracy.
Original VSOP87 Solution was write by FORTRAN 77 . It's too old to use.
Many Rewrite versions of VSOP87 is just a translation from FORTRAN.
This is the best VSOP87 library ever.
The Hotspot of VSOP87 is located in
(su, cu) = Math.SinCos(u);
Cost almost 90%+ CPU clocks.
I use default sincos function to ensure precision.
If anyone replace it with fast sincos funtion. this Algorithm will become much faster but less precision.
- Use VSOPResult class to manage calculate results.
- Use VSOPTime class to manage time.
Easy to convert time by callingVSOPTime.UTC
,VSOPTime.TAI
,VSOPTime.TDB
- Veryhigh performance per solution
- Useful Utility class. Such as checking planet available in specific version.
- Async Api
- Use [MessagePack](https://github.com/neuecc/MessagePack-CSharp#lz4-compression"MessagePack for C#") for binary serialize.
Initialization time becomes less than 10% of previous. - Brotli compression on source data. ~34Mb -> ~3MB with no precision lost.
- NuGet Package Manager
PM> NuGet\Install-Package VSOP87.NET -Version 1.1.6
using VSOP87;
Calculator vsop = new Calculator();
//Create VSOPTime using UTC .
DateTime Tinput = DateTime.Now;
VSOPTime vTime = new VSOPTime(Tinput.ToUniversalTime(),TimeFrame.UTC);
//Calculate Earth's present position with VSOP version D
var result=vsop.GetPlanetPosition(VSOPBody.EARTH, VSOPVersion.VSOP87D, vTime);
//VSOP version D Output LBR Coordinate.
//Neet cast to LBR result
VSOPResult_LBR Result_LBR = (VSOPResult_LBR)result;
//Print result
Console.WriteLine($"Version: {Enum.GetName(Result_LBR.Version)}");
Console.WriteLine($"Body: {Enum.GetName(Result_LBR.Body)}");
Console.WriteLine($"Coordinates Type: {Enum.GetName(Result_LBR.CoordinatesType)}");
Console.WriteLine($"Coordinates Reference: {Enum.GetName(Result_LBR.CoordinatesReference)}");
Console.WriteLine($"Reference Frame: {Enum.GetName(Result_LBR.ReferenceFrame)}");
Console.WriteLine($"Time UTC: {Result_LBR.Time.UTC.ToString("o")}");
Console.WriteLine($"Time TDB: {Result_LBR.Time.TDB.ToString("o")}");
Console.WriteLine("---------------------------------------------------------------");
Console.WriteLine(String.Format("{0,-33}{1,30}", "longitude (rad)", Result_LBR.l));
Console.WriteLine(String.Format("{0,-33}{1,30}", "latitude (rad)", Result_LBR.b));
Console.WriteLine(String.Format("{0,-33}{1,30}", "radius (au)", Result_LBR.r));
Console.WriteLine(String.Format("{0,-33}{1,30}", "longitude velocity (rd/day)", Result_LBR.dl));
Console.WriteLine(String.Format("{0,-33}{1,30}", "latitude velocity (rd/day)", Result_LBR.db));
Console.WriteLine(String.Format("{0,-33}{1,30}", "radius velocity (au/day)", Result_LBR.dr));
Console.WriteLine("===============================================================");
Critical Bug fix.
Bug fix.
Inpired from vsop2013, Add dynamical equinox and ecliptic
to ICRS frame
conversion.
Use MessagePack and brotli to compress original data.
Some bug fix.
Bug fix
Add VSOPTime.JulianDate
property
Delete float version. It's useful and nosense.
Add ELL coord to XYZ coord conversion.
Add ELL coord to LBR coord conversion.
add XYZ coord to LBR coord conversion
add LBR coord to XYZ coord conversion
function that convert ELL to XYZ is copy from VSOP2013.
This is a magic function way beyond my math level.
So I can't find how to inverse XYZ elements to ELL elements.
Need help.
Bug fix
Move to .NET7 for better performance.
Add async api
Add performance test framework
Add float version calculator VSOP87.CalculatorF
.
But no performance Improvement.
Code Cleaning.
Performance optimization.
A lot of new features.
Performance Optimization.
I make a data converter
Converting text data file into binary serialized file and embed in core DLL
All 6 version solution & All planets supported
Original data and solution download
ftp://ftp.imcce.fr/pub/ephem/planets/vsop87/
VSOP87 algorithm remastered in C#
It's a RAM db that 80's would never imaging a computer can hold that huge amout data
It's loaded into RAM when initiate VSOP calculator class
.NET 6 Runtime Windows x64
.NET 7 Runtime Windows x64
This Class provide double precision results.
Get Planet Position based on body, version, time.
Use Utility.AvailableBody(VSOPVersion ver)
to check all available body in version.
ibody
VSOPBody
Enum of all planet in VSOP87.
iver
VSOPVersion
Enum of all Version in VSOP87.
time
VSOPTime
A wrapper of Datetime
. Help converting between UTC & TDB.
VSOPResult
abstract class contain 6 variables of planet position.
should be explicit cast to VSOPResult_ELL
, VSOPResult_XYZ
, VSOPResult_LBR
.
Wrapper of GetPlanetPosition
,but async.
This Class Provide some useful function.
ver
VSOPVersion
Enum of Version in VSOP87.
List<VSOPBody>
All Available planets in this version.
ver
VSOPVersion
Enum of Version in VSOP87.
body
VSOPVersion
Enum of body in VSOP87.
bool
Is this version contain this body?
ver
VSOPVersion
Enum of Version in VSOP87.
CoordinatesType
Coordinates type based on version.
ver
VSOPVersion
Enum of Version in VSOP87.
CoordinatesReference
Coordinates reference based on version.
ver
VSOPVersion
Enum of Version in VSOP87.
TimeFrameReference
Time frame reference based on version.
A handy matrix multiply function
A
double[,]
Matrix A
B
double[,]
Matrix B
double[,]
Matrix C = AB.
xyz
double[]
Array of cartesian coordinate elements
double[]
Array of spherical coordinate elements
lbr
double[]
Array of spherical coordinate elements
double[]
Array of cartesian coordinate elements
This is a magic function I directly copy from VSOP2013.
It's way beyond my math level.
So I can't find how to inverse XYZ elements to ELL elements.
Need help.
ell
double[]
Array of elliptic coordinate elements
double[]
Array of cartesian coordinate elements
ell
double[]
Array of elliptic coordinate elements
double[]
Array of spherical coordinate elements
xyz
double[]
Array of cartesian coordinate elements that inertial frame of dynamical equinox and ecliptic.
double[]
Array of cartesian coordinate elements that inertial frame of ICRS equinox and ecliptic.
xyz
double[]
Array of cartesian coordinate elements that inertial frame of ICRS equinox and ecliptic.
double[]
Array of cartesian coordinate elements that inertial frame of dynamical equinox and ecliptic.
version
VSOPVersion
version of this result from calculator.
body
VSOPBody
Planet
time
VSOPTime
Time wrapper for VSOP
variables
double[]
Raw Data from calculator.
Create a new cartesian result from spherical result.
result
VSOPResult_LBR
Create a new Cartisian result from ellipitic result.
result
VSOPResult_ELL
VSOPVersion Version { get; }
VSOP version of this result.
VSOPBody Body { get; }
Planet of this result.
CoordinatesType CoordinatesType { get; }
Coordinates type of this result.
CoordinatesReference CoordinatesRefrence { get; }
Coordinates reference of this result.
ReferenceFrame ReferenceFrame { get; set;}
ReferenceFrame of this result. Set to ReferenceFrame.ICRSJ2000
or ReferenceFrame.DynamicalJ2000
will automatically change coordinate field.
'Dynamical frame of the date' is not supported.
'Barycentric Coordinates' is not supported.
'Elliptic Coordinates' is not supported.
VSOPTime Time { get; }
Input time of this result.
double[] Variables { get;}
Raw data of this result.
double x {get;}
Position x (au)
double y {get;}
Position y (au)
double z {get;}
Position z (au)
double dx {get;}
Velocity x (au/day)
double dy {get;}
Velocity y (au/day)
double dz {get;}
Velocity z (au/day)
Convert Result to Spherical coordinate.
Create a new spherical result from cartesian result.
version
VSOPVersion
version of this result from calculator.
body
VSOPBody
Planet
time
VSOPTime
Time wrapper for VSOP
ell
double[]
Raw result data from calculator.
VSOPVersion Version { get; }
VSOP version of this result.
VSOPBody Body { get; }
Planet of this result.
CoordinatesType CoordinatesType { get; }
Coordinates type of this result.
CoordinatesReference CoordinatesRefrence { get; }
Coordinates reference of this result.
ReferenceFrame ReferenceFrame { get; }
Reference frame of this result.
VSOPTime Time { get; }
Input time of this result.
double[] Variables { get;}
Raw data of this result.
double a {get;}
Semi-major axis (au)
double l {get;}
Mean longitude (rd)
double k {get;}
e*cos(pi) (rd)
double h {get;}
e*sin(pi) (rd)
double q {get;}
sin(i/2)*cos(omega) (rd)
double p {get;}
sin(i/2)*sin(omega) (rd)
Convert Result to Cartesian coordinate.
Convert Result to Spherical coordinate.
version
VSOPVersion
version of this result from calculator.
body
VSOPBody
Planet
time
VSOPTime
Time wrapper for VSOP
variables
double[]
Raw Data from calculator.
Create a new spherical result from cartesian result.
result
VSOPResult_XYZ
Create a new Spherical result from ellipitic result.
result
VSOPResult_ELL
VSOPVersion Version { get; }
VSOP version of this result.
VSOPBody Body { get; }
Planet of this result.
CoordinatesType CoordinatesType { get; }
Coordinates type of this result.
CoordinatesReference CoordinatesRefrence { get; }
Coordinates reference of this result.
ReferenceFrame ReferenceFrame { get; set;}
ReferenceFrame of this result. Set to ReferenceFrame.ICRSJ2000
or ReferenceFrame.DynamicalJ2000
will automatically change coordinate field.
'Dynamical frame of the date' is not supported.
'Barycentric Coordinates' is not supported.
'Elliptic Coordinates' is not supported.
VSOPTime Time { get; }
Input time of this result.
double[] Variables { get;}
Raw data of this result.
double l {get;}
longitude (rd)
double b {get;}
latitude (rd)
double r {get;}
radius (au)
double dl {get;}
longitude velocity (rd/day)
double db {get;}
latitude velocity (rd/day)
double dr {get;}
radius velocity (au/day)
Convert Result to Cartesian coordinate.
This class provide time convert and management for VSOP87.
Time to initialize VSOPTime.
DateTime dt
time struct
DateTime TAI
International Atomic Time
DateTime TT
Terrestrial Time (aka. TDT)
DateTime TDB
Barycentric Dynamical Time
VSOP87 use this time frame.
double JulianDate
Get Julian Date from TDB.
dt
DateTime
A Datetime of any frame.
SourceFrame
TimeFrame
Time frame of dt
TargetFrame
TimeFrame
Target time frame.
DateTime
Datetime of target time Frame.
dt
DateTime
Datetime to convert
double
Julian date.
double
Julian date to analyze.
dt
DateTime
Datetime Class.