summaryrefslogtreecommitdiff
path: root/ipl/procs/curves.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/procs/curves.icn')
-rw-r--r--ipl/procs/curves.icn520
1 files changed, 520 insertions, 0 deletions
diff --git a/ipl/procs/curves.icn b/ipl/procs/curves.icn
new file mode 100644
index 0000000..a3a3a2a
--- /dev/null
+++ b/ipl/procs/curves.icn
@@ -0,0 +1,520 @@
+############################################################################
+#
+# File: curves.icn
+#
+# Subject: Procedures to generate points on plain curves
+#
+# Author: Ralph E. Griswold
+#
+# Date: March 25, 2002
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# This file links procedure files that generate traces of points on various
+# plain curves.
+#
+# The first two parameters determine the defining position of the
+# curve:
+#
+# x x coordinate
+# y y coordinate
+#
+# The meaning of "definition position" depends on the curve. In some
+# cases it is the position at which plotting starts. In others, it
+# is a "center" for the curve.
+#
+# The next arguments vary and generally refer to parameters of the
+# curve. There is no practical way to describe these here. If they
+# are not obvious, the best reference is
+#
+# A Catalog of Special Plane Curves, J. Dennis Lawrence,
+# Dover Publications, Inc., New York, 1972.
+#
+# This book, which is in print at the time of this writing, is a
+# marvelous source of information about plane curves and is inexpensive
+# as well.
+#
+# The trailing parameters give the number of steps and the end points
+# (generally in angles) of the curves:
+#
+# steps number of points, default varies
+# lo beginning of plotting range, default varies
+# hi end of plotting range, default varies
+#
+# Because of floating-point roundoff, the number of steps
+# may not be exactly the number specified.
+#
+# Note: Some of the curves may be "upside down" when plotted on
+# coordinate systems in which the y axis increases in a downward direction.
+#
+# Caution: Some of these procedures generate very large values
+# in portions of their ranges. These may cause run-time errors when
+# used in versions of Icon prior to 8.10. One work-around is to
+# turn on error conversion in such cases.
+#
+# Warning: The procedures that follow have not been tested thoroughly.
+# Corrections and additions are most welcome.
+#
+# These procedures are, in fact, probably most useful for the parametric
+# equations they contain.
+#
+############################################################################
+#
+# Links: gobject, math, step
+#
+############################################################################
+
+link gobject
+link math
+link step
+
+procedure bullet_nose(x, y, a, b, steps, lo, hi)
+ local incr, theta
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + a * cos(theta),
+ y + b * tan(&pi / 2 - theta),
+ 0
+ )
+
+end
+
+procedure cardioid(x, y, a, steps, lo, hi)
+ local incr, theta, fact
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ fact := 2 * a * (1 + cos(theta))
+ suspend Point(
+ x + cos(theta) * fact,
+ y + sin(theta) * fact,
+ 0
+ )
+ }
+
+end
+
+procedure cissoid_diocles(x, y, a, steps, lo, hi)
+ local incr, theta, radius
+
+ /steps := 300
+ lo := dtor(\lo) | (-2 * &pi)
+ hi := dtor(\hi) | (2 * &pi)
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ radius := a * sin(theta) * cos(theta)
+ suspend Point(
+ x + radius * cos(theta),
+ y + radius * sin(theta),
+ 0
+ )
+ }
+
+end
+
+procedure cross_curve(x, y, a, b, steps, lo, hi)
+ local incr, theta
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + a / cos(theta),
+ y + b / sin(theta),
+ 0
+ )
+
+end
+
+procedure cycloid(x, y, a, b, steps, lo, hi)
+ local incr, theta
+
+ /steps := 100
+ lo := dtor(\lo) | 0
+ hi := dtor(\hi) | (8 * &pi)
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + a * theta - b * sin(theta),
+ y + a - b * cos(theta),
+ 0
+ )
+
+end
+
+procedure deltoid(x, y, a, steps, lo, hi)
+ local incr, theta
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + a * (2 * cos(theta) + cos(2 * theta)),
+ y + a * (2 * sin(theta) - sin(2 * theta)),
+ 0
+ )
+
+end
+
+procedure ellipse(x, y, a, b, steps, lo, hi)
+ local incr, theta
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + a * cos(theta),
+ y + b * sin(theta),
+ 0
+ )
+
+end
+
+procedure ellipse_evolute(x, y, a, b, steps, lo, hi)
+ local incr, theta
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + a * cos(theta) ^ 3,
+ y + b * sin(theta) ^ 3,
+ 0
+ )
+
+end
+
+procedure epitrochoid(x, y, a, b, h, steps, lo, hi)
+ local incr, theta, sum, fact
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ sum := a + b
+ fact := sum / b
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + sum * cos(theta) - h * cos(fact * theta),
+ y + sum * sin(theta) - h * sin(fact * theta),
+ 0
+ )
+
+end
+
+procedure folium(x, y, a, b, steps, lo, hi)
+ local incr, theta, radius
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ radius := (3 * a * sin(theta) * cos(theta)) /
+ (sin(theta) ^ 2 + cos(theta) ^ 2)
+ suspend Point(
+ x + radius * cos(theta),
+ y + radius * sin(theta),
+ 0
+ )
+ }
+
+end
+
+procedure hippopede(x, y, a, b, steps, lo, hi)
+ local incr, theta, mul
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ mul := a * b - b ^ 2 * sin(theta) ^ 2
+ if mul < 0 then next
+ mul := 2 * sqrt(mul)
+ suspend Point(
+ x + mul * cos(theta),
+ y + mul *sin(theta),
+ 0
+ )
+ }
+
+end
+
+procedure kampyle_exodus(x, y, a, b, steps, lo, hi)
+ local incr, theta, fact
+
+ /steps := 300
+ lo := dtor(\lo) | (-&pi / 2)
+ hi := dtor(\hi) | (3 * &pi / 2)
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ fact := a / cos(theta)
+ suspend Point(
+ x + fact,
+ y + fact * tan(theta),
+ 0
+ )
+ }
+
+end
+
+procedure kappa(x, y, a, b, steps, lo, hi)
+ local incr, theta, fact
+
+ /steps := 300
+ lo := dtor(\lo) | 0
+ hi := dtor(\hi) | (2 * &pi)
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ fact := a * cos(theta)
+ suspend Point(
+ x + fact / (0 ~= tan(theta)),
+ y + fact,
+ 0
+ )
+ }
+
+end
+
+procedure lemniscate_bernoulli(x, y, a, steps, lo, hi)
+ local incr, theta, fact
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ fact := a * cos(theta) / (1 + sin(theta) ^ 2)
+ suspend Point(
+ x + fact,
+ y + fact * sin(theta),
+ 0
+ )
+ }
+
+end
+
+procedure lemniscate_gerono(x, y, a, b, steps, lo, hi)
+ local incr, theta, fact
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ fact := a * cos(theta)
+ suspend Point(
+ x + fact,
+ y + sin(theta) * fact,
+ 0
+ )
+ }
+
+end
+
+procedure limacon_pascal(x, y, a, b, steps, lo, hi)
+ local incr, theta, fact
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ fact := b + 2 * a * cos(theta)
+ suspend Point(
+ x + fact * cos(theta),
+ y + fact * sin(theta),
+ 0
+ )
+ }
+
+end
+
+procedure line(x, y, x1, y1, steps)
+ local xincr, yincr
+
+ /steps := 100
+
+ xincr := (x1 - x) / (steps - 1)
+ yincr := (y1 - y) / (steps - 1)
+
+ every 1 to steps do {
+ suspend Point(x, y, 0)
+ x +:= xincr
+ y +:= yincr
+ }
+
+end
+
+procedure lissajous(x, y, a, b, r, delta, steps, lo, hi)
+ local incr, theta
+
+ /steps := 300
+ lo := dtor(\lo) | 0
+ hi := dtor(\hi) | (16 * &pi)
+ incr := (hi - lo) / steps
+
+ r := dtor(r)
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + a * sin(r * theta + delta),
+ y + b * sin(theta),
+ 0
+ )
+
+end
+
+procedure nephroid(x, y, a, steps, lo, hi)
+ local incr, theta
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + a * (3 * cos(theta) - cos(3 * theta)),
+ y + a * (3 * sin(theta) - sin(3 * theta)),
+ 0
+ )
+
+end
+
+# Needs to be checked out
+
+procedure parabola(x, y, a, steps, lo, hi)
+ local incr, theta, denom, radius
+
+ /steps := 300
+ lo := dtor(\lo) | -&pi
+ hi := dtor(\hi) | &pi
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ denom := 1 - cos(theta)
+ if denom = 0 then next
+ radius := 2 * a / denom
+ suspend Point(
+ radius * cos(theta),
+ radius * sin(theta),
+ 0
+ )
+ }
+
+end
+
+procedure piriform(x, y, a, b, steps, lo, hi)
+ local incr, theta, fact
+
+ /steps := 300
+ lo := dtor(\lo) | (-&pi / 2)
+ hi := dtor(\hi) | (3 * &pi / 2)
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ fact := 1 + sin(theta)
+ suspend Point(
+ x + a * fact,
+ y + b * cos(theta) * fact,
+ 0
+ )
+ }
+
+end
+
+procedure trisectrix_catalan(x, y, a, steps, lo, hi)
+ local incr, theta, radius
+
+ /steps := 300
+ lo := dtor(\lo) | (-2 * &pi)
+ hi := dtor(\hi) | (2 * &pi)
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ radius := a / cos(theta / 3) ^ 3
+ suspend Point(
+ x + radius * cos(theta),
+ y + radius * sin(theta),
+ 0
+ )
+ }
+
+end
+
+procedure trisectrix_maclaurin(x, y, a, b, steps, lo, hi)
+ local incr, theta, fact
+
+ /steps := 300
+ lo := dtor(\lo) | (-&pi / 2)
+ hi := dtor(\hi) | (&pi / 2)
+ incr := (hi - lo) / steps
+
+ every theta := step(lo, hi, incr) do {
+ fact := a * (1 - 4 * cos(theta) ^ 2)
+ suspend Point(
+ x + fact,
+ y + fact * tan(theta),
+ 0
+ )
+ }
+
+end
+
+procedure witch_agnesi(x, y, a, steps, lo, hi)
+ local incr, theta, fact
+
+ /steps := 300
+ lo := dtor(\lo) | (-&pi /2)
+ hi := dtor(\hi) | (&pi / 2)
+ incr := (hi - lo) / steps
+
+ fact := 2 * a
+
+ every theta := step(lo, hi, incr) do
+ suspend Point(
+ x + fact * tan(theta),
+ y - fact * cos(theta) ^ 2,
+ 0
+ )
+
+end