Task: Draw a clock




Go: package main

import (
	"golang.org/x/net/websocket"
	"flag"
	"fmt"
	"html/template"
	"io"
	"math"
	"net/http"
	"time"
)

var (
	Portnum  string
	Hostsite string
)

type PageSettings struct {
	Host string
	Port string
}

const (
	Canvaswidth  = 512
	Canvasheight = 512
	
	HourColor   = "#ff7373" 
	MinuteColor = "#00b7e4" 
	SecondColor = "#b58900" 
)

func main() {
	flag.StringVar(&Portnum, "Port", "1234", "Port to host server.")
	flag.StringVar(&Hostsite, "Site", "localhost", "Site hosting server")
	flag.Parse()
	http.HandleFunc("/", webhandler)
	http.Handle("/ws", websocket.Handler(wshandle))
	err := http.ListenAndServe(Hostsite+":"+Portnum, nil)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("server running")
}

func webhandler(w http.ResponseWriter, r *http.Request) {
	wsurl := PageSettings{Host: Hostsite, Port: Portnum}
	template, _ := template.ParseFiles("clock.html")
	template.Execute(w, wsurl)
}



func wshandle(ws *websocket.Conn) {
	for {
		hour, min, sec := time.Now().Clock()
		hourx, houry := HourCords(hour, Canvasheight/2)
		minx, miny := MinSecCords(min, Canvasheight/2)
		secx, secy := MinSecCords(sec, Canvasheight/2)
		msg := "CLEAR\n"
		msg += fmt.Sprintf("HOUR %d %d %s\n", hourx, houry, HourColor)
		msg += fmt.Sprintf("MIN %d %d %s\n", minx, miny, MinuteColor)
		msg += fmt.Sprintf("SEC %d %d %s", secx, secy, SecondColor)
		io.WriteString(ws, msg)
		time.Sleep(time.Second / 60.0)
	}
}



func MinSecCords(ctime int, radius int) (int, int) {
	

	theta := ((float64(ctime)*6 - 90) * (math.Pi / 180))
	x := float64(radius) * math.Cos(theta)
	y := float64(radius) * math.Sin(theta)
	return int(x) + 256, int(y) + 256
}



func HourCords(ctime int, radius int) (int, int) {
	
	theta := ((float64(ctime)*30 - 90) * (math.Pi / 180))
	x := float64(radius) * math.Cos(theta)
	y := float64(radius) * math.Sin(theta)
	return int(x) + 256, int(y) + 256
}








Ada: with Ada.Numerics.Elementary_Functions;
with Ada.Calendar.Formatting;
with Ada.Calendar.Time_Zones;

with SDL.Video.Windows.Makers;
with SDL.Video.Renderers.Makers;
with SDL.Events.Events;

procedure Draw_A_Clock is
   use Ada.Calendar;
   use Ada.Calendar.Formatting;
   Window   : SDL.Video.Windows.Window;
   Renderer : SDL.Video.Renderers.Renderer;
   Event    : SDL.Events.Events.Events;
   Offset   : Time_Zones.Time_Offset;

   procedure Draw_Clock (Stamp : Time)
   is
      use SDL.C;
      use Ada.Numerics.Elementary_Functions;
      Radi : constant array (0 .. 59) of int := (0 | 15 | 30 | 45 => 2,
                                                 5 | 10 | 20 | 25 | 35 | 40 | 50 | 55 => 1,
                                                 others => 0);
      Diam : constant array (0 .. 59) of int := (0 | 15 | 30 | 45 => 5,
                                                 5 | 10 | 20 | 25 | 35 | 40 | 50 | 55 => 3,
                                                 others => 1);
      Width  : constant int   := Window.Get_Surface.Size.Width;
      Height : constant int   := Window.Get_Surface.Size.Height;
      Radius : constant Float := Float (int'Min (Width, Height));
      R_1    : constant Float := 0.48 * Radius;
      R_2    : constant Float := 0.35 * Radius;
      R_3    : constant Float := 0.45 * Radius;
      R_4    : constant Float := 0.47 * Radius;
      Hour   : constant Hour_Number   := Formatting.Hour   (Stamp, Offset);
      Minute : constant Minute_Number := Formatting.Minute (Stamp, Offset);
      Second : constant Second_Number := Formatting.Second (Stamp);

      function To_X (A : Float; R : Float) return int is
         (Width / 2 + int (R * Sin (A, 60.0)));

      function To_Y (A : Float; R : Float) return int is
         (Height / 2 - int (R * Cos (A, 60.0)));

   begin
      SDL.Video.Renderers.Makers.Create (Renderer, Window.Get_Surface);
      Renderer.Set_Draw_Colour ((0, 0, 150, 255));
      Renderer.Fill (Rectangle => (0, 0, Width, Height));
      Renderer.Set_Draw_Colour ((200, 200, 200, 255));
      for A in 0 .. 59 loop
         Renderer.Fill (Rectangle => (To_X (Float (A), R_1) - Radi (A),
                                      To_Y (Float (A), R_1) - Radi (A), Diam (A), Diam (A)));
      end loop;
      Renderer.Set_Draw_Colour ((200, 200, 0, 255));
      Renderer.Draw (Line => ((Width / 2, Height / 2),
                              (To_X (5.0 * (Float (Hour) + Float (Minute) / 60.0), R_2),
                               To_Y (5.0 * (Float (Hour) + Float (Minute) / 60.0), R_2))));
      Renderer.Draw (Line => ((Width / 2, Height / 2),
                              (To_X (Float (Minute) + Float (Second) / 60.0, R_3),
                               To_Y (Float (Minute) + Float (Second) / 60.0, R_3))));
      Renderer.Set_Draw_Colour ((220, 0, 0, 255));
      Renderer.Draw (Line => ((Width / 2, Height / 2),
                              (To_X (Float (Second), R_4),
                               To_Y (Float (Second), R_4))));
      Renderer.Fill (Rectangle => (Width / 2 - 3, Height / 2 - 3, 7, 7));
   end Draw_Clock;

   function Poll_Quit return Boolean is
      use type SDL.Events.Event_Types;
   begin
      while SDL.Events.Events.Poll (Event) loop
         if Event.Common.Event_Type = SDL.Events.Quit then
            return True;
         end if;
      end loop;
      return False;
   end Poll_Quit;

begin
   Offset := Time_Zones.UTC_Time_Offset;

   if not SDL.Initialise (Flags => SDL.Enable_Screen) then
      return;
   end if;

   SDL.Video.Windows.Makers.Create (Win      => Window,
                                    Title    => "Draw a clock",
                                    Position => SDL.Natural_Coordinates'(X => 10, Y => 10),
                                    Size     => SDL.Positive_Sizes'(300, 300),
                                    Flags    => SDL.Video.Windows.Resizable);
   loop
      Draw_Clock (Clock);
      Window.Update_Surface;
      delay 0.200;
      exit when Poll_Quit;
   end loop;

   Window.Finalize;
   SDL.Finalise;
end Draw_A_Clock;