Well, today is Pearl Harbor Day! We should remember all those folks that died on that infamous day, and all the soldiers and civilians that allowed us to win the day during World War II.
Now, on to the subject of Vincenty’s formulae as started in this and this. I looked around recently and discovered formulae that does exactly what I am trying to do, so I decided not to reinvent the wheel anymore, and use what already exists. And, “what is that?” you ask.
“That” is a set of header files written for C++ that allows for calculating inverse distances and azimuths, among many other functions! Charles F. Karney wrote GeographicLib1, with the documentation found here. It also is written for many other programming languages as well, such as Python, Java, Fortran, etc. There is also a DMS header for conversion from and to degrees, minutes, seconds / decimal degrees, which I don’t go into here, as the input is in string format, and I have already written this file using double variables, so don’t wish to rewrite for strings.
Disclaimer: I am not a C++ programmer, so the defined program could be made better and more efficient, I’m sure! For me this is just a hobby.
So now, I am using these in my program to determine the inverse distance rather than Vincenty. Additionally, I am using Cmake for compiling, to increase the portability of the program across different operating systems (OSs), although in this case, I haven’t included different flags for different OSs. This example is done using the normal compilation procedure, (i.e., mkdir build && cd build, cmake .., make). This pulls in the required libraries so make will succeed. The CMakeLists.txt file looks like this:
Code
cmake_minimum_required (VERSION 3.17.0)project (karney)find_package (GeographicLib REQUIRED)if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)# Set a default build type for single-configuration cmake generators# if no build type is set.set (CMAKE_BUILD_TYPE "Release")endif ()add_executable (${PROJECT_NAME} karney.cpp)target_link_libraries (${PROJECT_NAME} ${GeographicLib_LIBRARIES})
The inportant lines are the find_package() and target_link_libraries(). For Linux, this assumes you have installed the GeographicLib package. So, after performing the below steps, we end with the program, karney, which is executed from the command line.
Note the third statement where I include iomanip for setprecision() as it makes a smaller file than using bits/stdc++.h. I also define the functions used. Next, we have the main body of the program:
Code
int main() { int choice {}; do {//cout <<"\033[2J\033[1;1H"; // clear screenmenu(); cout <<"Enter your choice: ";if( ! (cin >> choice)) { cout <<"Entry Error!"<< endl; return -1; }switch (choice) { case 1:inverse();break; case 2:direct();break; case 0:exit(0);break; default: cout <<"Invalid Choice."<< endl; } } while (choice !=0); return 0;}
Then we finish by including the actual functions as defined above:
At the top of both inverse and direct functions, we define a class name geod to use those functions. This makes the code a bit cleaner and easier to understand. Also I have included in the menu() function, a short explanation snippet using one of the included utilities, MagneticField, which determines the up-to-date magnetic declination for the entered location. This is very handy if one wishes to set a particular bearing when doing real angles in the field.
One last thing. If we wished to have a CMakeLists.txt file that could be used on other OSs, we could have something that looked like this:
Code
cmake_minimum_required( VERSION 3.6.2 )# For a new project it is sufficient to change only its name in the following lineset( PROJECT_NAME karney )project( ${PROJECT_NAME} )#set( CMAKE_BUILD_TYPE Debug )set( CMAKE_BUILD_TYPE Release )#[[ADD_DEFINITIONS(-g++ -O2 -fsigned-char -freg-struct-return -Wall -W -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Winline -Werror)]]if( WIN32 )set( CMAKE_CXX_FLAGS "/DWIN32 /D_WINDOWS /W3 /GR /EHsc /std:c++17 /D_UNICODE /DUNICODE" )set( CMAKE_CXX_FLAGS_DEBUG "/MDd /Zi /Ob0 /Od /RTC1 /std:c++17 /D_UNICODE /DUNICODE" )message( "Win settings chosen..." )elseif( ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" )set( CMAKE_CXX_FLAGS "-std=c++17 -Wall" )set( CMAKE_CXX_FLAGS_DEBUG "-g -std=c++17 -Wall" )message( "Mac settings chosen..." )elseif( UNIX )set( CMAKE_CXX_FLAGS "-std=c++17 -Wall" )set( CMAKE_CXX_FLAGS_DEBUG "-g -std=c++17 -Wall" )message( "Linux settings chosen..." )endif()# Inform CMake where the header files areinclude_directories( include )# Automatically add all *.cpp and *.h files to the projectfile ( GLOB SOURCES "./src/*.cpp""./include/*.h" )add_executable( ${PROJECT_NAME} ${SOURCES} )# Set the default project set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} )message( "CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}" )
For our purposes, this is way more complicated, so is shown for reference only. Note it will not compile without the find_package() and target_link_libraries() lines added. Have a wonderful day, and may God Bless!
Footnotes
C. F. F. Karney, GeographicLib, Version 2.7 (2025-11-06), https://geographiclib.sourceforge.io/C++/2.7↩︎