[Android Apps and Games] Tamasaka:
Coordinate axis

This script draws a single axis with scales which is snapped to concentric grid.

This axis can be linked with above graph paper.

Parameter 1 gives the size of arrow head.

Parameter 2 is the number of scales.

Parameter 3 indicates width of the scale.

Parameter 4 selects from solid line, dashed or dotted.

Codes for dashed and dotted lines are copied from acadoid's examples.

/* Coordinate axis ver. 1.00 */
headsize = 0;
scales = 5;
scalewidth = 3;
dash = 0;
if (LN.getNumberOfParameters() >= 1)
headsize = LN.getParameter(1); /* Head size, 0 ≤ Parameter(1) ≤ 3, 4 steps */
if (LN.getNumberOfParameters() >= 2)
scales = LN.getParameter(2); /* Number of scales, 1 ≤ Parameter(2) ≤ 15, 15 steps */
if (LN.getNumberOfParameters() >= 3)
scalewidth = LN.getParameter(3); /* Width of scale, 1 ≤ Parameter(3) ≤ 5, 5 steps */
if (LN.getNumberOfParameters() >= 4)
dash = LN.getParameter(4); /* Dashed line (0:solid, 1:dash, 2:dot), 0 ≤ Parameter(4) ≤ 2, 3 steps */
tipangle = 45;
headshape = 1;
width = LN.getWidth();
height = LN.getHeight();
scale = LN.getScale();
strokewidth = LN.getStrokeWidth();
theta = tipangle * Math.PI / 360;
step = width / 150 + scale * width / 25;
finestep = step / 5;
pi2 = Math.PI / 2;
scalewd = scalewidth * strokewidth / 2;
astep = Math.PI / 12;

x1 = LN.getX1();
y1 = LN.getY1();
x2 = LN.getX2();
y2 = LN.getY2();

x1 = step/2 + Math.floor((x1 - step/2) / step + 0.5) * step;
y1 = step/2 + Math.floor((y1 - step/2) / step + 0.5) * step;

angle = Math.atan2(y2 - y1, x2 - x1);
ag = Math.floor(angle / astep + 0.5) * astep;
reverse = ag + Math.PI;
distance = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
dg = Math.floor(distance * scales / (scales + 1) / step + 0.5) * step;
dtotal = dg * (scales + 1) / scales;
headlength = Math.min((headsize + 1) * strokewidth / Math.sqrt(Math.sin(theta)), dg /scales);

x2 = x1 + dtotal * Math.cos(ag);
y2 = y1 + dtotal * Math.sin(ag);

x21 = x2 + headlength * Math.cos(reverse + theta);
y21 = y2 + headlength * Math.sin(reverse + theta);
x22 = x2 + headlength * Math.cos(reverse - theta);
y22 = y2 + headlength * Math.sin(reverse - theta);

x17 = x2 + scalewd * Math.cos(ag + pi2);
y17 = y2 + scalewd * Math.sin(ag + pi2);
x18 = x2 + scalewd * Math.cos(ag - pi2);
y18 = y2 + scalewd * Math.sin(ag - pi2);

x11 = x1 + scalewd * Math.cos(ag + pi2);
y11 = y1 + scalewd * Math.sin(ag + pi2);
x12 = x1 + scalewd * Math.cos(ag - pi2);
y12 = y1 + scalewd * Math.sin(ag - pi2);
xmin = Math.min(x1, x11, x12, x17, x18, x2, x21, x22);
ymin = Math.min(y1, y11, y12, y17, y18, y2, y21, y22);
xmax = Math.max(x1, x11, x12, x17, x18, x2, x21, x22);
ymax = Math.max(y1, y11, y12, y17, y18, y2, y21, y22);

if (headshape >= 2) {
x2m = (x21 + x22) / 2;
y2m = (y21 + y22) / 2;
x1m = (x11 + x12) / 2;
y1m = (y11 + y12) / 2;
}
else {
x2m = (x21 * 2 + x22 * 2 + x2) / 5;
y2m = (y21 * 2 + y22 * 2 + y2) / 5;
x1m = (x11 * 2 + x12 * 2 + x1) / 5;
y1m = (y11 * 2 + y12 * 2 + y1) / 5;
}

LN.setStrokeCap(0);
LN.setClip(xmin, ymin, xmax, ymax);
if (headsize > 0) {
LN.drawFilledQuadrangle(x2, y2, x21, y21, x2m, y2m, x22, y22);
}

dgstep = dg / scales;
xstep = dgstep * Math.cos(ag);
ystep = dgstep * Math.sin(ag);
x01 = x1 + scalewd * Math.cos(ag + pi2);
y01 = y1 + scalewd * Math.sin(ag + pi2);
x02 = x1 + scalewd * Math.cos(ag - pi2);
y02 = y1 + scalewd * Math.sin(ag - pi2);
LN.setStrokeWidth(strokewidth/2);
for (i = 1; i <= scales; i++) {
x01 += xstep;
y01 += ystep;
x02 += xstep;
y02 += ystep;
LN.drawLine(x01, y01, x02, y02);
}
LN.setStrokeWidth(strokewidth);
if (dash) {
size = Math.min(width, height);
if (dash == 1)
dashing1 = 0.005 * size;
else
dashing1 = (LN.getStrokeCap() == 1) ? strokewidth : 0.5;
dashing2 = (LN.getStrokeCap() == 1) ? dashing1 : dashing1 + 2 * strokewidth;
LN.setDashing(dashing1, dashing2);
}
LN.drawLine(x1, y1, x2m, y2m);