/* CMD:Flatline

 Line Simplifier 1.01 by GLYPH (11/06/1995)

 E-Mail: y82s1@unb.ca

 Removes useless points that lie in a straight line, like when you use TEXT
 to make a block-letter 'L' and you get 50 points in a straight line up
 the side of the 'L', you can use this to nuke them.

 * ONLY WORKS ON 2-D POLYS ON THE Z-AXIS, NOT 3-D.
 * WORKS BEST WHEN USED ON ONE POLY AT A TIME
 * CAN HAVE FUNNY RESULTS IF POLYS HAVE LOTS OF HOLES
 * AFFECTS ALL POLYS IN LAYER

 **** CANNOT BE UNDONE ****

 It's best when you're making logos with splines.
 If you freeze a spline and you get too many points,
 put it alone on a layer and run this macro.

*/

	mxx="LWModelerARexx.port"
	signal on error
	signal on syntax
	check = addlib("rexxmathlib.library",0,-30,0)
	mxx_add = addlib(mxx,0)
	call main
	if (mxx_add) then call remlib(mxx)
	exit

	syntax:
	error:
	t=Notify(1,'!Rexx Script Error','@'ErrorText(rc),'Line 'SIGL)
	if (mxx_add) then call remlib(mxx)
	exit


main:

call req_begin "FLATLINE v1.0 by GLYPH"
id_ang = req_addcontrol("Flatten Angles Less Than (±°)", N, 0)
call req_setval id_ang, 2.0, 1.0
if (~req_post()) then return
flatang = req_getval(id_ang)
call req_end
call MERGEPOINTS()
tagged = 1
psofar = 0
pass = 1
do forever
	call FLATTEN
	psofar = psofar + flat - 1
	pass = pass + 1
	if tags < 2 then do
		if psofar = 0 then call notify(1,"Already flat.")
		if psofar > 0 then call notify(1,psofar' points removed.')
		return
	end
end

FLATTEN:
n = xfrm_begin()
if n<3 then do
	call notify(1,"Must have at least 3 points.")
	exit
end
call meter_begin (n+1-tagged), "Reading Points..."
do i = tagged to n
    xyz = xfrm_getpos(i)
    parse var xyz x.i y.i z.i
    call meter_step
end
call meter_end
call xfrm_end

box = boundingbox()
parse var box zz x1 x2 y1 y2 z1 z2
outx = max(x1,x2) + 1
xlo = outx - 0.5
xhi = outx + 0.5
ylo = -1
yhi = 1
zlo = -1
zhi = 1
flat = 1
flatten.1 = 0
tags = 0
call meter_begin (n-tagged), "Flattening Lines (pass "pass")"
if n < (tagged+1) then return
do i = tagged+1 to n
 h = i-1
 j = i+1
 if j>n then j = 1
 if x.j ~= x.h then do
	slopa = (y.j - y.h)/(x.j - x.h)
 end
 if x.j = x.h then do
	slopa = 0
	if (y.j - y.h) < 0 then slopa = -99999999
	if (y.j - y.h) > 0 then slopa = 99999999
 end
 if x.i ~= x.h then do
	slopb = (y.i - y.h)/(x.i - x.h)
 end
 if x.i = x.h then do
	slopb = 999999999
	if (y.i - y.h) < 0 then slopb = -99999999
	if (y.i - y.h) > 0 then slopb = 99999999
 end

 actn = slopa
 call ARCTAN
 thetaa = th
 actn = slopb
 call ARCTAN
 thetab = th
 offang = abs(thetaa - thetab)
 if offang <= flatang then do
	 oldflat = flat-1
	 if flatten.oldflat = (i-1) then do
		tags = tags + 1
		if tags = 1 then tagged = i
	 end
	 if flatten.oldflat ~= (i-1) then do
	  flatten.flat = i
	  flat = flat + 1
	 end
 end
 call meter_step
end
call meter_end

if flat = 1 then return
n = xfrm_begin()
call meter_begin (flat-1), "Flattening Lines..."
do f = 1 to (flat-1)
	i = flatten.f
	call xfrm_setpos i, outx 0 0
    call meter_step
end
call xfrm_end

call SEL_MODE('USER')
call SEL_POINT('CLEAR')
call SEL_POINT('SET', 'VOLUME', xlo ylo zlo, xhi yhi zhi)
call CUT()
return

ARCTAN:
pi = 3.1415926385897932384626
actu = actn
if actu < -1 then th = 90+(atan(1/abs(actn)) * 180 / pi)
if (actu < 1.00001)&(actu > -1.00001) then th = atan(actn) * 180 / pi
if actu > 1 then th = 90-(atan(1/actn) * 180 / pi)
return

    Source: geocities.com/g_fyffe/lw

               ( geocities.com/g_fyffe)