2021-05-21 23:38:30 +00:00
|
|
|
|
|
|
|
const TWO_PI = 2* Math.PI;
|
|
|
|
|
|
|
|
// The problem with the trig inverse functions on
|
|
|
|
// a full circle is that the sector information will be lost
|
|
|
|
// Choosing to use arcsin because you can get back the
|
|
|
|
// sector with the help of the original coordinates
|
|
|
|
function reifyasin(x,y,asin_angle){
|
|
|
|
if(x >= 0 && y >= 0){
|
|
|
|
return asin_angle;
|
|
|
|
} else if(x >= 0 && y < 0){
|
|
|
|
return Math.PI - asin_angle;
|
|
|
|
} else if(x < 0 && y < 0){
|
|
|
|
return Math.PI - asin_angle;
|
|
|
|
} else {
|
|
|
|
return TWO_PI + asin_angle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// rebase and angle so be between -pi and pi
|
|
|
|
// rather than 0 to 2PI
|
|
|
|
function rebaseNegative(angle){
|
|
|
|
if(angle > Math.PI){
|
|
|
|
return angle - TWO_PI;
|
|
|
|
} else {
|
|
|
|
return angle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// rebase an angle so that it is between 0 to 2pi
|
|
|
|
// rather than -pi to pi
|
|
|
|
function rebasePositive(angle){
|
|
|
|
if(angle < 0){
|
|
|
|
return angle + TWO_PI;
|
|
|
|
} else {
|
|
|
|
return angle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Hour Scriber is responsible for drawing the numeral
|
|
|
|
* on the screen at the requested angle.
|
|
|
|
* It allows for the font to be changed on the fly.
|
|
|
|
*/
|
|
|
|
class HourScriber {
|
|
|
|
constructor(radius, numeral_font, draw_test, bg_colour_supplier, numeral_colour_supplier, hour){
|
|
|
|
this.radius = radius;
|
|
|
|
this.numeral_font = numeral_font;
|
|
|
|
this.draw_test = draw_test;
|
|
|
|
this.curr_numeral_font = numeral_font;
|
|
|
|
this.bg_colour_supplier = bg_colour_supplier;
|
|
|
|
this.numeral_colour_supplier = numeral_colour_supplier;
|
|
|
|
this.hours = hour;
|
|
|
|
this.curr_hour_x = -1;
|
|
|
|
this.curr_hour_y = -1;
|
|
|
|
this.curr_hours = -1;
|
|
|
|
this.curr_hour_str = null;
|
|
|
|
this.last_draw_time = null;
|
|
|
|
}
|
|
|
|
setNumeralFont(numeral_font){
|
|
|
|
this.numeral_font = numeral_font;
|
|
|
|
}
|
|
|
|
toString(){
|
|
|
|
return "HourScriber{numeralfont=" + this.numeral_font.getName() + ",hours=" + this.hours + "}";
|
|
|
|
}
|
|
|
|
draw(){
|
|
|
|
var changed = false;
|
|
|
|
if(this.curr_hours != this.hours || this.curr_numeral_font !=this.numeral_font){
|
|
|
|
var background = this.bg_colour_supplier();
|
|
|
|
g.setColor(background[0],background[1],background[2]);
|
|
|
|
this.curr_numeral_font.draw(this.curr_hour_str,
|
|
|
|
this.curr_hour_x,
|
|
|
|
this.curr_hour_y);
|
2021-05-23 22:03:38 +00:00
|
|
|
//console.log("erasing old hour display:" + this.curr_hour_str + " color:" + background);
|
2021-05-21 23:38:30 +00:00
|
|
|
var hours_frac = this.hours / 12;
|
|
|
|
var angle = TWO_PI*hours_frac;
|
|
|
|
var dimensions = this.numeral_font.getDimensions(this.hours);
|
|
|
|
// we set the radial coord to be in the middle
|
|
|
|
// of the drawn text.
|
|
|
|
var width = dimensions[0];
|
|
|
|
var height = dimensions[1];
|
|
|
|
var delta_center_x = this.radius*Math.sin(angle) - width/2;
|
|
|
|
var delta_center_y = this.radius*Math.cos(angle) + height/2;
|
|
|
|
this.curr_hour_x = screen_center_x + delta_center_x;
|
|
|
|
this.curr_hour_y = screen_center_y - delta_center_y;
|
|
|
|
this.curr_hour_str = this.numeral_font.hour_txt(this.hours);
|
|
|
|
// now work out the angle of the beginning and the end of the
|
|
|
|
// text box so we know when to redraw
|
|
|
|
// bottom left angle
|
|
|
|
var x1 = delta_center_x;
|
|
|
|
var y1 = delta_center_y;
|
|
|
|
var r1 = Math.sqrt(x1*x1 + y1*y1);
|
|
|
|
var angle1 = reifyasin(x1,y1,Math.asin(x1/r1));
|
|
|
|
// bottom right angle
|
|
|
|
var x2 = delta_center_x;
|
|
|
|
var y2 = delta_center_y - height;
|
|
|
|
var r2 = Math.sqrt(x2*x2 + y2*y2);
|
|
|
|
var angle2 = reifyasin(x2,y2,Math.asin(x2/r2));
|
|
|
|
// top left angle
|
|
|
|
var x3 = delta_center_x + width;
|
|
|
|
var y3 = delta_center_y;
|
|
|
|
var r3 = Math.sqrt(x3*x3 + y3*y3);
|
|
|
|
var angle3 = reifyasin(x3,y3, Math.asin(x3/r3));
|
|
|
|
// top right angle
|
|
|
|
var x4 = delta_center_x + width;
|
|
|
|
var y4 = delta_center_y - height;
|
|
|
|
var r4 = Math.sqrt(x4*x4 + y4*y4);
|
|
|
|
var angle4 = reifyasin(x4,y4,Math.asin(x4/r4));
|
|
|
|
if(Math.min(angle1,angle2,angle3,angle4) < Math.PI && Math.max(angle1,angle2,angle3,angle4) > 1.5*Math.PI){
|
|
|
|
angle1 = rebaseNegative(angle1);
|
|
|
|
angle2 = rebaseNegative(angle2);
|
|
|
|
angle3 = rebaseNegative(angle3);
|
|
|
|
angle3 = rebaseNegative(angle4);
|
|
|
|
this.angle_from = rebasePositive( Math.min(angle1,angle2,angle3,angle4) );
|
|
|
|
this.angle_to = rebasePositive( Math.max(angle1,angle2,angle3,angle4) );
|
|
|
|
} else {
|
|
|
|
this.angle_from = Math.min(angle1,angle2,angle3,angle4);
|
|
|
|
this.angle_to = Math.max(angle1,angle2,angle3,angle4);
|
|
|
|
}
|
|
|
|
//console.log(angle1 + "/" + angle2 + " / " + angle3 + " / " + angle4);
|
|
|
|
//console.log( this.angle_from + " to " + this.angle_to);
|
|
|
|
this.curr_hours = this.hours;
|
|
|
|
this.curr_numeral_font = this.numeral_font;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
if(changed ||
|
|
|
|
this.draw_test(this.angle_from, this.angle_to, this.last_draw_time) ){
|
|
|
|
var numeral_color = this.numeral_colour_supplier();
|
|
|
|
g.setColor(numeral_color[0],numeral_color[1],numeral_color[2]);
|
|
|
|
this.numeral_font.draw(this.curr_hour_str,this.curr_hour_x,this.curr_hour_y);
|
|
|
|
this.last_draw_time = new Date();
|
|
|
|
//console.log("redraw digit:" + this.hours);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = HourScriber;
|