[Android Apps and Games] Tamasaka:
Exponential curve

As analog of the above "Sine curve", this script draws a exponential curve.

Parameter 1 is curvature in arbitrary unit.

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

Parameter 3 is the resolution of the curve which is approximated by a polygonal line. When parameter 2 selects dashed or dotted line, it adjusts resolution automatically.

Parameter 4 is the switch to draw baseline.

Parameter 5 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.

/* Exponential ver.1.11 */
curvature = 3;
dash = 0;
resolution = 20;
baseline = 0;
snap = 2;
if (LN.getNumberOfParameters() >= 1)
curvature = LN.getParameter(1); /* Curvature, 1 ≤ Parameter(1) ≤ 5, 5 steps */
if (LN.getNumberOfParameters() >= 2)
dash = LN.getParameter(2); /* Dashed line (0:solid, 1:dashed, 2:dotted) , 0 ≤ Parameter(2) ≤ 2, 3 steps */
if (LN.getNumberOfParameters() >= 3)
resolution = Math.floor(LN.getParameter(3)); /* Resolution, 10 ≤ Parameter(3) ≤ 60, 26 steps */
if (LN.getNumberOfParameters() >= 4)
baseline = LN.getParameter(4); /* Baseline (1:draw), 0 ≤ Parameter(4) ≤ 1, 2 steps */
if (LN.getNumberOfParameters() >= 5)
snap = LN.getParameter(5); /* Grid (0:free, 1:end free, 2:end fine, 3:coarse), 0 ≤ Parameter(5) ≤ 3, 4 steps */

width = LN.getWidth();
height = LN.getHeight();
scale = LN.getScale();
if (dash <= 0) {
dash = Math.abs(dash);
autoresolution = false;
}
else
autoresolution = true;
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);
ymin = Math.min(y1, y2);
ymax = Math.max(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));

xpitch = (x2 - x1) / resolution;
ypitch = curvature / resolution;

for (xplot = x2, yplot = y2, j = 1; j <= resolution; j++) {
LN.drawLine(xplot, yplot, xplot -= xpitch, yplot = y1 + (y2 - y1) / Math.exp(j * ypitch));
}