############################################################################
#
# File: curves.icn
#
# Subject: Procedures to generate points on plain curves
#
# Author: Ralph E. Griswold
#
# Date: October 1, 1997
#
############################################################################
#
# 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
This page produced by UniDoc on 2021/04/15 @ 23:59:45.