[Android Apps and Games] Tamasaka:
Sine curve

This script draws a sine curve up to 3 cycles.

Parameter 1 is the number of quarter cycles.

Parameter 2 shifts phase of cycle in 1/8 Pi units.

Parameter 3 selects line type from solid line, dashed line or dotted line.

Parameter 4 is the resolution of one cycle. The curve is approximated by a polygonal line. When parameter 2 selects dashed or dotted line, it adjusts resolution automatically.

Parameter 5 is the switch to draw baseline.

Parameter 6 is the switch for snapping to grid. 0 draws free from grid. 1 is for the start point snaps to coarse grid while the end point is free. 2 is for the start point snaps to coarse grid while the end point snaps to 1/5 fine grid. 3 is for both points snap to coarse grid.

/* Sine ver.1.11 */
quartercycles = 4;
phaseshift = 0;
dash = 0;
cycleresolution = 32;
baseline = 0;
snap = 2;
autoresolution = 1;
if (LN.getNumberOfParameters() >= 1)
quartercycles = LN.getParameter(1); /* Quarter cycles, 1 ≤ Parameter(1) ≤ 12, 12 steps */
if (LN.getNumberOfParameters() >= 2)
phaseshift = LN.getParameter(2); /* Phase-shift (in Pi/8 units), 0 ≤ Parameter(2) ≤ 4, 5 steps */
if (LN.getNumberOfParameters() >= 3)
dash = LN.getParameter(3); /* Dashed line (0:solid, 1:dashed, 2:dotted) , 0 ≤ Parameter(3) ≤ 2, 3 steps */
if (LN.getNumberOfParameters() >= 4)
cycleresolution = LN.getParameter(4); /* Resolution, 20 ≤ Parameter(4) ≤ 80, 16 steps */
if (LN.getNumberOfParameters() >= 5)
baseline = LN.getParameter(5); /* Baseline (1:draw), 0 ≤ Parameter(5) ≤ 1, 2 steps */
if (LN.getNumberOfParameters() >= 6)
snap = LN.getParameter(6); /* Grid (0:free, 1:end free, 2:end fine, 3:coarse), 0 ≤ Parameter(6) ≤ 3, 4 steps */

width = LN.getWidth();
height = LN.getHeight();
scale = LN.getScale();
if (dash <= 0) {
dash = Math.abs(dash);
autoresolution = false;
}
else
autoresolution = true;
cycles = quartercycles / 4;
resolution = Math.floor(cycleresolution * cycles);
shift = phaseshift * Math.PI / 8;
x1 = LN.getX1();
y1 = LN.getY1();
x2 = LN.getX2();
y2 = LN.getY2();

if (snap > 0) {
step = width / 150 + scale * width / 25;
finestep = step / 5;
x1 = step / 2 + Math.floor((x1 - step / 2) / step + 0.5) * step;
y1 = step / 2 + Math.floor((y1 - step / 2) / step + 0.5) * step;
}
if (snap == 2) {
x2 = x1 + Math.floor((x2 - x1 - finestep / 2) / finestep + 0.5) * finestep;
y2 = y1 + Math.floor((y2 - y1 - finestep / 2) / finestep + 0.5) * finestep;
}
if (snap == 3) {
x2 = step / 2 + Math.floor((x2 - step / 2) / step + 0.5) * step;
y2 = step / 2 + Math.floor((y2 - step / 2) / step + 0.5) * step;
}

xmin = Math.min(x1, x2);
xmax = Math.max(x1, x2);
if (y1 < y2) {
ymin = 2 * y1 - y2;
ymax = y2;
}
else {
ymin = y2;
ymax = 2 * y1 - y2;
}
LN.setClip(xmin, ymin, xmax, ymax);

if (baseline) {
strokewidth = LN.getStrokeWidth();
LN.setStrokeWidth(strokewidth / 2);
LN.drawLine(x1, y1, x2, y1);
LN.setStrokeWidth(strokewidth);
}

if (dash) {
strokewidth = LN.getStrokeWidth();
if ( LN.getStrokeCap() == 1) {
dashing1 = (dash == 1) ? Math.max(8, strokewidth * 2) : strokewidth;
dashing2 = (dash == 1) ? dashing1 / 2 : strokewidth * 2;
}
else {
dashing1 = (dash == 1) ? Math.max(6, strokewidth * 1.2) : 0.5;
dashing2 = (dash == 1) ? dashing1 + strokewidth : strokewidth * 2;
}
LN.setDashing(dashing1, dashing2);
}

if (dash && autoresolution)
resolution = Math.floor(Math.max(Math.abs((x2 - x1) / (dashing1 + dashing2)), 6 * cycles));

xpitch = (x2 - x1) / resolution;
phasepitch = cycles * 2 * Math.PI / resolution;

i = 0;
xplot = x1;
yplot = y1 + (y2 - y1) * Math.sin(shift);
while (i++ < resolution) {
LN.drawLine(xplot, yplot, xplot += xpitch, yplot = y1 + (y2 - y1) * Math.sin(i * phasepitch + shift));
}