Rotation Notations

I was writing some code to perform some celestial calculations.  A lot of it handled changes in positions from certain rotations (orbits, revolutions).  There are also instances where time is treated as a rotation (ex: 1 hour of rotation is 15 degrees).  The best notation for the rotation depends on what is being done.  Here are the rotation notations that might be used.

  • Radians
  • Degrees
    • Decimal Degrees
    • Degrees, Minutes, Seconds
  • Hours
    • Decimal Hours
    • Hours, Minutes, Seconds

Conversion from one to another is easy.  What I did find challenging is ensuring that the right conversion had been performed before working with it.  The trig functions expect to always receive radians.  More than once I made the mistake of converting to the wrong unit before performing a calculation.  Rather then continue forward on a path that has many opportunities for mistakes I made a single class to represent rotations that can be used in various scenarios.  It will always internally represent rotations in degrees.  If I want to explicitly convert the class to a specific type there are methods to explicitly convert to any of the other rotation types.

Instances of this custom type also can be assigned a preferred notation. This preferred notation is used when printing it to the output stream. This allows a preferred format to be assigned without risking making any conversion mistakes.

The interface for the class and the support class follows.

#include <stdio.h>
#include <cmath>
#include <iostream>

typedef double Degree;
typedef double  Hour;
typedef double Minute;
typedef double Second;
typedef double Radian;

enum RotationNotation {

class Rotation;

struct HMS {
    Hour H;
    Minute M;
    Second S;

struct DMS {
    Degree D;
    Minute M;
    Second S;
} ;

std::ostream& operator << (std::ostream& o, const HMS& h);
std::ostream& operator << (std::ostream& o, const DMS& d);
std::ostream& operator << (std::ostream& o, const Rotation a);

double sin(const Rotation& source);
double cos(const Rotation& source);

Hour RadToHour(const Radian );
Hour HMSToHour(const HMS& hms);
Hour DMSToHour(const DMS&);
Hour DegToHour(const Degree degrees);

DMS RadToDMS(const Radian);
DMS DegToDMS(const Degree degrees);
DMS HourToDMS(const Hour hour);

HMS RadToHMS(const Radian);
HMS DegToHMS(const Degree degrees);
HMS HourToHMS(const Hour);

Degree RadToDeg(const Radian);
Degree DMSToDeg(const DMS& );
Degree HMSToDeg(const HMS&);
Degree HourToDeg(const Hour hour);

Radian HourToRad(const Hour);
Radian HMSToRad(const HMS& );
Radian DMSToRad(const DMS& );
Radian DegToRad(const Degree);

class Rotation { 
        Degree _degrees;
        RotationNotation _notation;
        Rotation(const Rotation& source);
        RotationNotation getNotation() const;
        void setNotation(RotationNotation);

        const Degree getDegrees() const;
        const Hour getHours() const ;
        const Minute getRadians() const ;
        const DMS getDMS() const ;
        const HMS getHMS() const ;

        void setDegrees(const Degree degree) ;
        void setHours(const Hour hour)  ;
        void setRadians(const Radian rad)  ;
        void setDMS(const DMS& dms)  ;
        void setHMS(const HMS& hms)  ;

Download Code 2.0 KB



Future of Microsoft Edge

Faster Updates, Cross Platform, 4 Channels



Microsoft had made an announcement some time ago stating that they were adopting Chromium as the foundation of the Edge browser. They are making more information available about their plans. A computer will be able to have up to 4 Edge. In addition to the general release version there will be a beta , development, and canary channel where canary is the most experimental channel.

Microsoft is going to make a web view control available. This is a feature I wish had been available a couple of years ago. I worked on a project in which it was necessary to insert a Chromium based web view and that required making modifications to the Chromium source. Compiling Chromium can take hours!

Microsoft Edge is the only browser that has achieved a 100% score in accessibility evaluation. Microsoft is planning to make contributions to Chromium which should help improve the scores of Chromium based browsers across the board.  One example of a change coming from Microsoft is a media query for detecting when a user has turned on high contrast in either their computer or browser. The web developer can choose to change the appearance of a page accordingly.

Windows Biometric sign in is also going to be available to web sites (see navigator.credentials.get). This allows for a more secure way of logging in that doesn’t require a password. Edge also has a hardware backed feature named “Play Ready” that allows for secure playback of premium media.

The user agent-string for Edge Chromium will be Edg (that’s not a type, there is no E on the end). Note that the non-chromium version of edge uses the user token Edge instead. But it is recommended that instead of using the user agent string for enabling or disabling functionality in a web page it is better to use feature detection; new features are being added to browsers all the time and relying on the user agent alone can lead to a page not using a feature that was actually available within a browser.  Edge gets supports for module import and much better much better speech synthesis.

What’s In My Bag? Windows To Go: Windows on USB

When I’m travelling for work there are a number of items that I make sure are in my travel bag.  These include a USB-C charger (almost all of my electronics can charge over USB-C now); a copy of any recent projects I’ve worked on (sometimes I need to hop in to help a team member); and a computer.

The operating system on that computer may vary.  Sometimes I travel with a Windows machine, sometimes a Linux machine, and other times a Mac.  Regardless of the operating system, I usually always have a Windows To Go drive.

The last item is something that is probably a little more obscure.  Since Windows 8, there have been a special type of USB drives that are different in one aspect: they appear as a fixed drive to the computer, even though they are connected to a USB port.  These drives were specifically made for making a portable Windows experience on a USB drive.

It is possible to make bootable Windows environments on other USB drive, but there are some differences.  If you have a Windows ISO you can make a bootable Windows USB drive with a number of tools.  I recommend using Rufus to make the drive.  Though there are other options (including one that is a part of Windows Enterprise Edition), Rufus doesn’t care much about the drive properties.  It will just write the data to the drive in a bootable format.

With any type of USB drive you’ll be able to boot up with little to no trouble and do initial setup on the drive.  The difference will show up when you start installing programs.  Some programs will only install to a fixed drive.  Visual Studio is one such program.  If you have a USB drive that isn’t Windows To Go certified, then chances are that it will appear as a removable drive to the computer.  Visual Studio will not install to a removable drive.

With a non-certified drive it will generally refuse to install.  If you know that the programs of interest to you don’t care about the drive type, there’s a couple of other reasons why you still may want to consider a Windows To Go certified drive.  One is performance. There was a minimum performance requirement that these drives had to achieve as a part of their certification.  However, now there are other solid state drives available that are much faster than the available Windows To Go drive (such as the Thunderbolt 3 only Samsung X5 drives).  Another consideration is security.  Some of the Windows To Go drives have hardware implemented encryption and include the option of voiding the contents of the drive under some conditions that you can define (such as the wrong password being entered at bootup too many times).

The best practice, if you plan to work with any sensitive data, is to not store it on a portable drive, if possible. But if you must, then encryption is an uncompromising need. Whether or not a Windows To Go drive is necessary for you may only be known after you review your needs.

One significant drawback of Windows To Go drives is you cannot perform a major Windows Update on it. The installation can receive Windows security updates though.  When there is a major Windows Update if you want to install it, it’s necessary to format the entire drive and start from scratch.

For my needs, I have a Super Talent 128 GB USB 3.0 drive (for speed) and a Western Digital 500 GB mechanical drive (much slower, but I can work with larger projects using it).  If you choose to do this with a certified drive, make sure you read the drive’s instructions, before you begin writing your Windows Image to it.  Some drives come with their own software that must be used for making the image and if you start off formatting the drive then you’ve already destroyed the software that you need (and it may not be readily available for download from the company’s website).

If your project needs call for a Windows To Go certified drive, I’ve found 4 available on Amazon.  Here are the links to them (affiliate links).

// // // //


SignageLive + BrightSign

Signangelive is a platform for managing content on digital signage.  It works on a variety of devices, including BrightSign, Chrome OS, LG webOS, Samsung Tizen TVs, and Windows.  I recently used evaluated Signagelive for use with a BrightSign project.

One of the units of deployent on Signangelive is an HTML Widget.  An HTML Widget is a zip file of HTML assets with a manifest and a .wgt file extension.  Prior to now, the only place I’ve really seen Widgets used is on Samsung’s Tizen based platforms.  The Samsung smart watches, TVs, and the Tizen powered phones support HTML applications through Widgets.  The Widgets and other presentation items (such as videos, pictures, or other displayable elements) can be scheduled to run on a device and the platform will take care of the rest.

For the solution I am working on, I packaged it as a widget.  The only additional file that I had to make to do this was a config.xml along with a PNG image to use as an icon.  I updated the WGT into the signage live system, scheduled it, and sometime later the widget was running on the BrightSign.  This deployment process would work great for a production environment, but it doesn’t work as well for development where you might want to make a quick change and refresh.  I found two solutions for this.


One solution was to deploy an IFRAME whose address pointed back to my development machine.  With this solution, if I want to make a quick change, I can make the change on my local file system and then refresh my view on the device.  Refreshing the video on the device could be done by pressing the reset button, but that takes too long.  If you have Chrome installed, you can connect to port 2999 of the BrightSign unit; connect to the browser instance; and then press the refresh menu option on your local browser.  It results in the BrightSign refreshing too.

Remote File System Browsing

You can also upload files directly to the BrightSign. Connect to the BrightSign’s IP address (without the port specified).  There’s a tab labeled “SD” (for the SD card). From there you can upload content to any place on the file system.  After your files are copied, you can either reset the device (which in my opinion takes too long) or connect to the devices IP and refresh the view as described in the IFRAME section.


Accessing Node

I initially ran into another problem with running my code in a widget.  I mentioned in another blog posts that BrightSign does not support the HTML5 APIs for persistent storage.  The solution that I suggest for this is using NodeJS within BrightSign.  Signagelive runs the code that was packaged inside of a widget in an IFRAME.  As it turns out IFRAMES on BrightSign does not support NodeJS functionality, but that is easily overcome.  The IFRAME that contains the widget has access to the parent window.  The child window cannot call NodeJS functions directly, but it can grab a reference to its parent and invoke the parent’s NodeJS functionality.  To minimize the difference between code run within and outside of the WGT and IFRAME we can coalesce the possible locations of a needed function. To get access to the required function, I used the following.

window.require = window.require || window.parent.require;

File System Access

My attempts to access the file system would initially fail while hosted in Signagelive. To fix this it was necessary to modify AutoRun.brs. When the BrightSign version of Signagelive creates its HTML window (of type roHtmlWidget in BrightScript) it does not configure the window for file system access. To fix this the WebWindowHTML function in Autorun.brs needs a couple of items added, storage_path and storage_quota.

Function WebWindowHTML(index% as integer, url$ as string, RectX as integer, RectY as integer, RecWidth as integer, RecHeight as integer) as Object
	webRect=CreateObject("roRectangle", RectX, RectY, RecWidth, RecHeight)
    is = {
        port: 3000
    webPageConfig = {
        nodejs_enabled: true,
        storage_path: "SD:"
        storage_quota: 1073741824        
        inspector_server: is,
        brightsign_js_objects_enabled: false,
        javascript_enabled: true,
        mouse_enabled: true,
        scrollbar_enabled: false,
        storage_path: "SD:",
        storage_quota: 1073741824,   
		port: m.msgPort,
        security_params: {
            websecurity: false,
            camera_enabled: true,
            insecure_https_enabled: false
		url: url$
    webhtmlWidget = CreateObject("roHtmlWidget", webRect, webPageConfig)

	return webhtmlWidget
End Function

I talked to an engineer at Signagelive about addressing this issue.  I do not know how frequently Signagelive makes updates., but this change may appear in future versions of the software making it unnecessary.  If you happen to read this close to the time that the post was made, the change might not have rolled out yet.  You can make the change yourself but beware of a possible risk.  There is a possibility that an update will be made and pushed out to your device that does not yet contain this change. If that happens you would want your code to fail gracefully instead of simply crashing.


Simplified Sidereal Time

While preparing for a full moon / blue moon, I was looking at an algorithm for calculating sidereal time and had a mini epiphany. The algorithm is basically an elaborate modulo operation. Modulo is generally applied to integer values, but it can be used with decimal numbers and even fractions.

For the algorithm that I have generally used, a lot of the calculations are only for converting the date to some linear expression of time. The calendar that is usually used does not express time linearly.

The amount of time from the beginning of one month to the beginning of another month could be 28 to 31 days. With linear representations of dates, a subtraction operation is all that is needed to know the amount of time between two moments in time.

In JavaScript, this linear representation of time is shown by calling getTime() on a date object. The time value for 2019 January 10 @16:40:20 UTC  is 1547138420000. This value is the number of milliseconds since another date and time. This time and date is also 00:00:00 Sidereal time. The number of milliseconds in a sidereal day (23 hours 56 minutes 4.1 seconds) is 86164100. For any date after 2019-01-10T16:40:20 we could get the Sidereal time by doing the following:

  • Acquire the getTime() value for the date in question.
  • Subtract 1547138420000 from that value.
  • Get the modulo 86164100 for the resulting value.
  • Multiply the result by 24/86164100.

The result of these operations is the sidereal time in decimal. If you want to convert it to hour:minute:second format do the following:

var hour = Math.floor(result);
var minute = (result % 1) * 60;
var second = (minute % 1) * 60;
minute = Math.floor(minute)