Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/librasteve/raku-physics-navigation

A Physics::Measure abstraction layer providing Latitude, Longitude, Bearing , Position, Course and Buoy classes.
https://github.com/librasteve/raku-physics-navigation

navigation physics raku raku-module rakulang

Last synced: 2 months ago
JSON representation

A Physics::Measure abstraction layer providing Latitude, Longitude, Bearing , Position, Course and Buoy classes.

Awesome Lists containing this project

README

        

[![License: Artistic-2.0](https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg)](https://opensource.org/licenses/Artistic-2.0)
[![raku-physics-navigation -> DH](https://github.com/librasteve/raku-Physics-Navigation/actions/workflows/navigation-weekly.yaml/badge.svg)](https://github.com/librasteve/raku-Physics-Navigation/actions/workflows/navigation-weekly.yaml)

# raku Physics::Navigation

This module is an abstraction on [Physics::Measure](https://github.com/librasteve/raku-Physics-Measure) that provides Latitude, Longitude, Bearing, Position, Course and Buoy classes.

Provides Measure objects that have value, units and error and can be used in many common physics calculations. Uses [Physics::Unit](https://github.com/librasteve/raku-Physics-Unit) and [Physics::Error](https://github.com/librasteve/raku-Physics-Error).

# Instructions
```zef --verbose install Physics::Navigation```

and, conversely, ```zef uninstall Physics::Navigation```

**For a gentler introduction to and explanation of these features, please refer to [raku Yacht Navigation](https://github.com/librasteve/raku-Yacht-Navigation) for a descriptive Jupyter notebook**

# Synopsis

```perl6
use lib '../lib';
use Physics::Navigation;
use Physics::Measure;

# objects can be set up longhand as in Physics::Measure, now joined by Latitude, Longitude, etc.
$Physics::Measure::round-val = 0.1;

my Distance $d1 .=new( value => 42, units => 'nmile' ); say ~$d1;
my Time $t1 .=new( value => 1.5, units => 'hr' ); say ~$t1;
my Latitude $lat1 .=new( value => 45, compass => ); say ~$lat1;

# the emoji ♓️ operator shorthand does all that the Physics::Measure emoji ♎️ operator does
my $d2 = ♓️'42 nmile'; say ~$d2;
my $t2 = ♓️'1.5 hr'; say ~$t2;
my $s2 = $d2 / $t2; say ~$s2.in('knots');

# and then some - parses final NEWS letter to determine lat or long
my $lat2 = ♓️<43°30′30″S>; say ~$lat2;
my $long1 = ♓️<45°W>; say ~$long1;
my $long2 = ♓️<22°E>; say ~$long2;

# the .in conversion method works and the identity 1° lat === 1 nautical mile is preserved
my $lat3 = in-lat( $d1 ); say ~$lat3;
my $d3 = $lat2.in('nmiles'); say ~$d3;

# you can do "Measure math" using the standard operators <[+-*/**]>
my $d4 = $d3 * 2; say ~$d4;
my $lat4 = $lat2 - $lat1; say ~$lat4;

# Bearings can be True(T) or Magnetic(M), with Variation and Deviation [Vw|Ve|Dw|De]
$Physics::Navigation::variation = ♓️<7°Vw>;

my $bear1 = ♓️<80°T>; say ~$bear1;
my $bear2 = ♓️<43°30′30″M>; say ~$bear2;
my $bear3 = $bear2 + $bear1.M; say ~$bear3;

# here's how to steer your boat to Port (Pt) or Starboard (Sb)
my $steer = ♓️<50°Pt>; say ~$steer;
my $bear4 = $bear2 + $steer; say ~$bear4;
my $bear5 = $bear4.back; say ~$bear5; #and take a back bearing

try {
my $bear-nope = $bear2 + $bear1;
}
if $! { say "Can't mix True & Magnetic ... $!" }

my Position $start .=new( $lat1, $long1 ); say ~$start;
my Position $finish .=new( $lat2, $long2 ); say ~$finish;

# get great circle distance and initial azimuth bearing
say ~$start.haversine-dist($finish).in('km');
say ~$start.forward-azimuth($finish);

# make a Vector (angle + distance) and move by that amount
my $vector = $start.diff($finish); say ~$vector;
my $finish2 = $start.move($vector); say ~$finish2;

# use Measure math to make Velocity objects
my $dur = ♓️'3 weeks'; say ~$dur;
my $vel = $vector.divide: $dur; say ~$vel;
my $vector2 = $vel.multiply: $dur; say ~$vector2;

my $pos-A = Position.new( ♓️<51.5072°N>, ♓️<0.1276°W> );
my $pos-B = Position.new( ♓️<51.5072°N>, ♓️<0.1110°W> );
my $pos-C = Position.new( ♓️<51.5072°N>, ♓️<0.1100°W> );

# there are Fixes, Estimated positions and Transits
my $fix-A = Fix.new( direction => ♓️<112°T>, location => $pos-A );
my $fix-B = Fix.new( direction => ♓️<25°T>, location => $pos-B );

my $ep = Estimate.new( :$fix-A, :$fix-B ); say ~$ep;

my $tr = Transit.new( :$pos-A, :$pos-B ); say $tr.aligned( $pos-C );

# Course objects handle Course To Steer, Tidal Flow, Course Over Ground (and leeway)
%course-info = ♓️<112°Pt>;
my $tidal-flow = Velocity.new( θ => ♓️<112°T>, s => ♓️'2.2 knots' );
my Course $course .= new( over-ground => ♓️<22°T>, :$tidal-flow ); say ~$course;
say $course.speed-over-ground.in('knots');

# Buoy objects know their shape, colour, light pattern, etc.
my $scm = SouthCardinal.new( position => $pos-A ); say ~$scm;
my $ncm = NorthCardinal.new( position => $pos-A ); say ~$ncm;

# Lateral Buoys know about IALA standards
$IALA = A;
my $plm = PortLateral.new( position => $pos-B ); say ~$plm;

# use .light-defn to get an English description
say $plm.light-defn;

# .duration and .patterm methods also support SVG animation
say "SVG-animation: duration is {$plm.light-svg.duration}s, pattern is: [{$plm.light-svg.pattern}];";
```

# Summary

The family of Physics::Navigation, Physics::Measure, Physics::Unit, Physics::Error and Physics::Constants raku modules is a consistent and extensible toolkit intended for science and education. It provides a comprehensive library of both metric (SI) and non-metric units, it is built on a Type Object foundation, it has a unit expression Grammar and implements math, conversion and comparison methods.

# Contribution

You are welcome to contribute in any way - please open a pull request.

Any feedback is welcome to librasteve / via the github Issues above.

Copyright (c) Henley Cloud Consulting Ltd. 2021-2023