1
0
Fork 0
fgdata/Nasal/canvas/draw/compass.nas

108 lines
3.8 KiB
Text

#
# canvas.draw library - compass rose module
# created 12/2018 by jsb
# WARNING: this is still under development, interfaces may change
#
var CompassRose = {
VERSION: 1.0,
Style: {
new: func() {
var obj = {
parents: [CompassRose.Style, canvas.draw.marksStyle.new()],
mark_count: 36, # number of marks, count = 360 / interval
label_count: 12, # number of text labels (degrees)
label_div: 10, # >0 div. degr. by this for text labels
circle_color: [255,255,255,1],
mark_color: [255,255,255,1],
label_color: [255,255,255,1],
center_mark: 0, # draw a mark in the center of the rose
font: "sans", # fontsize for labels
font_weight: "bold", # fontsize for labels
fontsize: 0, # fontsize for labels
nesw: 1, # replace labels 0,90,180,270 by N,E,S,W
};
obj.setMarkLength(0.1);
obj.setSubdivisionLength(0.5);
return obj;
},
setMarkCount: func(value) {
me.mark_count = num(value) or 0;
return me;
},
setLabelCount: func(value) {
me.label_count = num(value) or 0;
return me;
},
# divide course by this value before creating text label. (try 10, 1 or 0)
setLabelDivisor: func(value) {
me.label_div = num(value) or 10;
return me;
},
setFontSize: func(value) {
me.fontsize = num(value) or 26;
return me;
},
},
};
# draw a compass rose
# cgroup canvas group, marks and lables will be created as children
CompassRose.draw = func(cgroup, radius, style=nil) {
if (style == nil) {
style = me.Style.new();
}
cgroup = cgroup.createChild("group", "compass-rose");
if (style.center_mark) {
var center = cgroup.createChild("path","center");
var l = radius * 0.1;
center.setStrokeLineWidth(1).setColor(style.circle_color)
.moveTo(-l,0).line(2*l,0).moveTo(0,-l).line(0,2*l);
}
if (style.baseline_width > 0) {
var c = cgroup.createChild("path", "circle");
c.circle(radius)
.setStrokeLineWidth(style.baseline_width)
.setColor(style.circle_color);
}
if (style.mark_count > 0) {
var marks = canvas.draw.marksCircular(cgroup, radius, 360 / style.mark_count, 0, 360, style);
marks.setStrokeLineWidth(style.mark_width);
}
var fontsize = style.fontsize;
if (style.fontsize == 0) {
fontsize = math.round(math.sqrt(radius) * 1.4);
}
if (style.label_count > 0) {
var labels = cgroup.createChild("group", "labels")
.createChildren("text", style.label_count);
var offset = (style.mark_offset < 0 ? -1 : 1) * style.mark_length * radius;
var rot = 2*math.pi/style.label_count;
var font = canvas.font_mapper(style.font, style.font_weight);
forindex (i; labels) {
var t = n = int(i*360 / style.label_count);
if (style.label_div > 0) t = int(n / style.label_div);
var txt = sprintf("%d", t);
if (style.nesw) {
if (n == 0) txt = "N";
elsif (n == 90) txt = "E";
elsif (n == 180) txt = "S";
elsif (n == 270) txt = "W";
}
labels[i]
.setText(txt)
.setFontSize(fontsize)
.setFont(font)
.setColor(style.label_color)
.setAlignment("center-"~(style.mark_offset < 0 ? "top" : "bottom"))
.setTranslation(0,-radius-offset)
.setCenter(0,radius+offset)
.setRotation(i*rot);
}
}
return cgroup;
};