Coder Social home page Coder Social logo

librasteve / raku-physics-navigation Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 0.0 113 KB

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

License: Artistic License 2.0

Raku 99.04% Dockerfile 0.96%
navigation raku rakulang raku-module physics

raku-physics-navigation's Introduction

License: Artistic-2.0 raku-physics-navigation -> DH

raku Physics::Navigation

This module is an abstraction on 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 and 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 for a descriptive Jupyter notebook

Synopsis

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 => <N> );		  say ~$lat1;

# the emoji ♓️ <pisces> operator shorthand does all that the Physics::Measure emoji ♎️ <libra> 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<leeway> =  ♓️<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

raku-physics-navigation's People

Contributors

librasteve avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

raku-physics-navigation's Issues

v2 Backlog

version 2 backlog

  • Transit and Fix
  • Estimates with 3 Fixes (cocked hat)
  • Uncertainty
  • Passages - Milestones and Legs
  • Tide ladders (rule of 12ths)
  • Beaufort scale
  • Sea state scale
  • Visibility scale
  • Vessels

Example bug

In synopsis:

my $steer = ♓️<50Pt°>; 

Should be

my $steer = ♓️<50°Pt>; 

subtract bug

~ > crag 'say Position.new(|<90°N>,|<0°E>).haversine-dist(Position.new(|<90°S>,|<0°E>))'
Type check failed in assignment to $!value; expected but got Rat (-180.0)
in method subtract at /Users/stephenroe/.rakubrew/versions/moar-2023.10/share/perl6/site/sources/4766748DEDB36DB0A67B8D5A5975DD72ADCC42B0 (Physics::Navigation) line 124
in sub infix:<-> at /Users/stephenroe/.rakubrew/versions/moar-2023.10/share/perl6/site/sources/A0D4A6EF999000570AC03B6392BF106C6FF0A757 (Physics::Measure) line 641
in method Δ at /Users/stephenroe/.rakubrew/versions/moar-2023.10/share/perl6/site/sources/4766748DEDB36DB0A67B8D5A5975DD72ADCC42B0 (Physics::Navigation) line 333
in method haversine-dist at /Users/stephenroe/.rakubrew/versions/moar-2023.10/share/perl6/site/sources/4766748DEDB36DB0A67B8D5A5975DD72ADCC42B0 (Physics::Navigation) line 337
in block at EVAL_4 line 13
in sub eval-me at /Users/stephenroe/.rakubrew/versions/moar-2023.10/share/perl6/site/sources/F8E217C0C27DD20CFB45A2555525D22D8164967E (App::Crag) line 44
in sub MAIN at /Users/stephenroe/.rakubrew/versions/moar-2023.10/share/perl6/site/resources/02FA54A625EEFAC10EEC6511EFE713B0F92CDA32 line 35
in block at /Users/stephenroe/.rakubrew/versions/moar-2023.10/share/perl6/site/resources/02FA54A625EEFAC10EEC6511EFE713B0F92CDA32 line 4
in sub MAIN at /Users/stephenroe/.rakubrew/versions/moar-2023.10/share/perl6/site/bin/crag line 3
in block at /Users/stephenroe/.rakubrew/versions/moar-2023.10/share/perl6/site/bin/crag line 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.