ParaPlot package
By Xah Lee
Last Modified 1998/04.
Created 1994.

Preface and Copyright Notice

(* :Context: ParaPlot` *)

(* :Title: ParaPlot *)

(* :Author: Xah Lee *)

(* : Copyright 1994-1998 by Xah Lee. 
	Permission is hereby granted to make copies of
	this file for nonprofit purposes, provided this copyright notice
	is left intact.
*)

(* :Summary:
This package exports the function ParaPlot.
ParaPlot is like ParametricPlot with extra options to plot tangent, secant,
normal lines, parallel curves, caustics, evolutes, radial, concoid,
and inversion of a curve. These features are useful for studing plane curves.
*)

(* :Keywords: graphics, geometry, calculus, curve, plot, tangent, secant,
	normal, parallel, caustics, involute, evolute, radial, concoid,
	inversion, pedal
*)

(* :Mathematica Version: 3.0 *)
(* :Package Version: 3.4, 1998/03 *)
(* :History:
Version 3.4. 199803xx. Converted the package to 3.0 format. Minor editing here and there.
Version 3.33 199609xx. Added DeleteCases in the main body of ParaPlot so the output grahpics does not contain empty lists or lists containing graphics directives only.
Also fixed a precaution so that single item fed to Options can be
specified whether it has the head List. e.g. CurveColorFunction->{Hue[#]&} or
CurveColorFunction->(Hue[#]&) are both okay.
Version 3.32 199510xx. Loading package do not switch off messages.
Version 3.3 199508xx. Added option to plot inversion and involute.
Version 3.2 19950520. Added option to plot Conchoid, Pedal, Evolute,
Radial, and Osculating circle.
Version 3.1 19950500. Added two new options Caustic & Parallel.
Version 3.0 19950400. Complete redesign and rewrite.
Version 2.0 19940700. First published on CompuServe.
*)

(* :Sources: 
	Mathematica Programming: 
	Maeder, Roman: Programming In Mathematica, 2nd ed. chapter 1-3.
	Smith, Cameron; Blachman, Nancy: The Mathematica Graphics Guidebook.

	Mathematics of plane curves: (in order of my preference)
	Yates, R. C.; Curves and their Properties
	(The National Council of Teachers of Mathematics, 1952).
	Lockwood, E.H.: A book of Curves. (Cambridge Uni. Press, 1961).
	Lawrence, J. D.; A Catalog of Special Plane Curves (Dover, 1972).
	Seggern, D. v.; CRC Standard Curves and Surfaces (CRC Press; 1994).
	Encyclopedia Britannica, Geometry: Special Curves.
*)
		
(* :Warning: 
*)

(* :Limitations: *)

(* :Discussion:
(This package is available on MathSource Item#:/Enhancements/Graphics/2D/0207-986)
This package exports the function ParaPlot[]. ParaPlot is similar to
ParametricPlot, with extended functionality. Special options include: 
* Varing the curve color with t. (from gray to blue by default) 
* Plot curves without drawing their asymptotes. 
* Optional list of t rendered as red dots on the curve and its value
  superscribed. 
* Plot tangent, secant, or normal lines at these points. 
* Plot parallel, catacaustic, diacaustic, concohid, evolute, involute,
  pedal of a curve. 
* User have full control over these options and their PlotStyle. 
* Fully documented on-line. Type ?ParaPlot for details.
This package is especially suited for study of special plane curves.

I wrote several other packages. They can be found on MathSource <http://www.MathSource.com/> or on my home page. If you have any problem with my packages, I'll be happy to help out.

Xah Lee, xah@xahlee.org
http://xahlee.org/

You should always be able to find me by searching the web.

*)

BeginPackage

BeginPackage["ParaPlot`", "Utilities`FilterOptions`"]

(*This cell contain all symbols defined in this package,
Useful in development stage *)

Needs["Utilities`FilterOptions`"];

(*exported symbols*)
Clear[PlotCurve,PlotDot,PlotParameterValue,NormalLineLength,TangentLineLength,CausticLineLength,CausticOrigin,ParallelCurveOffset,SecantConnection,ConchoidSetting,PedalPoint,InversionCircle,PlotOsculatingCircle,PlotInvolute,PlotEvolute,PlotRadial]

(*exported options, style related*)
Clear[CurveColorFunction,CurveStyle,DotStyle,LineStyle,NormalLineStyle,TangentLineStyle,CausticLineStyle,SecantLineStyle]

(*modules*)
Clear[NormalLineGP,TangentLineGP,ParallelDotGP,VectorLength,UnitV,reflDirVector,CausticLineGP,SecantLineGP,ConchoidLineAndDotGP,PedalLineAndDotGP,InversionDotGP,InvoluteLineAndDotGP,curvatureGPs,ColorLinesGP,StyleInjector]

Clear[ ArcLengthPartition,ParaPlot, ParaPolarPlot]

Exported symbols usage definition

This cell should contain all exported symbols.
(* may miss some symbol, need to check *)
ArcLengthPartition, ParaPlot, ParaPolarPlot,
PlotCurve, PlotDot,	PlotParameterValue,	NormalLineLength, TangentLineLength, CausticLineLength, CausticOrigin, SecantConnection, ParallelCurveOffset, ConchoidSetting, PedalPoint, InversionCircle, PlotOsculatingCircle,PlotInvolute, PlotEvolute, PlotRadial

CurveColorFunction, CurveStyle, DotStyle, LineStyle, NormalLineStyle, TangentLineStyle, CausticLineStyle, SecantLineStyle

\(ArcLengthPartition::usage\  = \ 
      "ArcLengthPartition[{xf[t],yf[t]},{t,tmin,tmax}, n] returns a list of t parameters {tmin, t1, t2,..., tmax}, such that the points {xf[ti],yf[ti]} cut the parametric curve into n seqments of equal length. For example, to cut the Archimedean spiral into 8 equal length segments, ArcLengthPartition[ {t Cos@t, t Sin@t}, {t,0, 4 Pi}, 8]"; 


    ParaPlot::usage\  = \ 
      "ParaPlot[{x[t],y[t]},{t,tmin,tmax,(dt)},({t1,t2,...,tn}), (options...)] plots the parametric curve where the curve color vary with t. The optional tlist {t1, t2,...} are rendered as dots on the curve with the value of t superscribed. If this list is not present, Range[tmin,tmax, dt] will be used. The default dt is (tmax-tmin)/4. To see the special options for ParaPlot, type Options[ParaPlot]. Each option is documented on-line. Example: ParaPlot[{t Cos[t],t Sin[t]}, {t, 0, 4 2 Pi, 8 Pi/125}, SecantConnection->{10,1}, PlotDot->False, SecantLineStyle->Table[Hue[i], {i,0,1,1/125}], PlotRange->All, AspectRatio->Automatic]"; 


    ParaPolarPlot::usage\  = \ 
      "ParaPolarPlot[ {distF[t], angleF[t]},{t,tmin,tmax,(dt)}, ({t1,t2,...,tn}), (options...)] plots the parametric formula {distF[t], angleF[t]} in polar coordinates. distF[t] and angleF[t] are the distance and the angle functions at time t. The optional tlist {t1, t2,...} are rendered as dots on the curve with the value of t superscribed. If this list is not present, Range[tmin,tmax, dt] will be used. The default dt is (tmax-tmin)/4. ParaPolarPlot takes the same options as ParaPlot. Type Options[ParaPlot] to see the list. Example:  ParaPolarPlot[ {t Abs[Cos[4 t]], Cos[3 t]}, {t,0, 5 2 Pi}, CurveColorFunction->{Hue[#]&}, PlotRange->All,	PlotDivision->30, PlotPoints->30, AspectRatio->Automatic]"; \)

\(PlotCurve::usage = 
      "PlotCurve is an option for ParaPlot. It specifies whether the curve should be drawn. The default is PlotCurve->True. Example:(* Hypotrochoid, 23 sec.*) ParaPlot[ {(4 Cos[t])/7 + (3 Cos[(4 t)/3])/7, (4 Sin[t])/7 - (3 Sin[(4 t)/3])/7}, {t, 0, 18.22, 0.067}, PlotRange->All, AspectRatio->Automatic, Ticks->None, PlotCurve->False, Axes->None, DotStyle->Table[{PointSize[.015],Hue[i,3.33 (.3-i),1]},{i,0,.3,.3/40}]]"; 

    
PlotDot::usage = 
      "PlotDot is an option for ParaPlot. It specifies whether the dots on the curve generated by the parameter t list should be plotted. The default is PlotDot->True."; 


    PlotParameterValue::usage = 
      "PlotParameterValue is an option for ParaPlot. It specifies whether the the value of t should be superscripted in the plot. The default is PlotParameterValue->False. Example: ParaPlot[ {t Cos[t], Sin[t]}, {t,0,3 2 Pi,1}, PlotParameterValue->True]"; 


    NormalLineLength::usage = 
      "NormalLineLength is an option for ParaPlot. It specifies the length of normal lines to be plotted. The default NormalLineLength ->0, will plot no normal lines. Example:(* Parabola & its Evolute, 13 sec. *) ParaPlot[ {t, t^2}, {t, -3, 3, .1}, NormalLineLength->15, NormalLineStyle->{Hue[0]}, PlotDot->False, AspectRatio->Automatic, PlotRange->{{-6,6},{-2,5}}]"; 


    TangentLineLength::usage = 
      "TangentLineLength is an option for ParaPlot. It specifies the length of tangent lines to be plotted. The default TangentLineLength ->0, will plot no tangent lines. Use TangentLineStyle to control how you want these lines to be rendered. Example: (*"TangentCrawl", 20 sec.*) ParaPlot[ {t, Cos[t] Sin[t] +t}, {t, -5, 10 }, Range[3, 5 , 0.05], TangentLineLength->6, PlotDot->False,  PlotRange->{{-6,11},{-6,11}}, AspectRatio->Automatic]"; 

    
CausticLineLength::usage = 
      "CausticLineLength is an options for ParaPlot. It specifies the length of catacaustic rays (lines) to be plotted. That is, lines will be drawn starting from CausticOrigin->{0,0} (the default) toward the parametric curve, and reflected off from it.  The default CausticLineLength->0, will plot no rays. CausticLineLength->(negative number) will draw diacaustic rays (i.e. rays refracted from the curve instead of being reflected) Example: (* Parabola and its optical property, 11 sec *) ParaPlot[ {(1 -2 x + x^2)/4+1, x},{x, -2, 4, .4}, CausticLineLength->5, CausticOrigin->{2,1}, PlotDot->False, AspectRatio->Automatic]"; 


    CausticOrigin::usage = "see ?CausticLineLength"; 


    ParallelCurveOffset::usage = 
      "ParallelCurveOffset is an option for ParaPlot. It specifies the offset distance from the curve to its parallel curve. The default ParallelCurveOffset->{0}, will plot no parallel curves. You can specify more than one parallel curve by giving a list {offset1, offset2,...}. Example: (* Lemniscate of Bernoulli, 42 sec. *) ParaPlot[{Cos[t]/(1+Sin[t]^2), Sin[t] Cos[t]/(1+Sin[t]^2)}, {t, 0, 2 Pi,.05}, ParallelCurveOffset->{.3,-.3}, PlotDot->False, DotStyle->{Hue[0], Hue[.7]}, AspectRatio->Automatic, PlotRange->All]"; 


    SecantConnection::usage = 
      "SecantConnection is an option for ParaPlot, specifing which dots on the curve to be connected to which. SecantConnection->{m,n} will connect every (1+i*n)th point with (1+i*n+m)th point, where i starts from 0. The default SecantConnection->{1,1} will not plot any secant line. The example below will connect every other point with the 6th point that comes after them. Example:(* Circle, 14 sec.*)  ParaPlot[{Cos[t/5],Sin[t/5]}, {t, 0, 30,1}, SecantConnection->{6,2}, SecantLineStyle->{Hue[.4,.8,.7]}, PlotParameterValue->True, DotStyle->{{PointSize[.02],Hue[.4,.8,.7]},{PointSize[.02],Hue[.55]}}, Ticks->None, PlotRange->All, AspectRatio->Automatic]"; 


    ConchoidSetting::usage = 
      "ConchoidSetting is an option for ParaPlot. ConchoidSetting->{{x,y},{n1,n2,...}} specifies the plotting of concoid with respect to the point {x,y}, and length {n1, n2,...}. Default is ConchoidSetting->{{0,0},{0}}. Use the option DotStyle and LineStlye  to control rendering. (*Conchoid is a method to generate new curves. Given any curve C and a point O, a concoid of that curve with respect to O and offset k is defined. Let P be any point on the curve. Draw a line passing O and P. Mark off points p1 and p2 on the line with distance +k,-k from P. The locus of p1 and p2 is the concoid of the curve with respect to O and offset k.*) Example: (* Conchoid of Nicomedes;  10 sec.*) ParaPlot[{x,1},{x,-3,3,.2}, ConchoidSetting->{{0,0},{-2,2,1}}, DotStyle->{Hue[0],Hue[.7],Hue[.8]}, PlotDot->False,AspectRatio->Automatic]"; 


    PedalPoint::usage = 
      "PedalPoint is an option for ParaPlot. PedalPoint->{x,y} plots the pedal of a curve with repect to {x,y} together with tangent lines showing how pedals are generated. Default is PedalPoint->None. Use LineStyle and DotStyle to control the rendering of lines and dots.  What is the Pedal of a curve? Pedal is a way of defining a new curve from a given curve and a point. Given a curve C (a circle, for example), and a point M. Draw a tangent at any point P on the curve. Mark a point Q on the tangent line such that MQ is perpendicular to the tangent line. The locus of Q is the pedal of the given curve with respect to the point M. Example: (* Parabola and Line; 11 sec.*) ParaPlot[{t,1/2 t^2},{t,-2,2,.2}, PedalPoint->{0,1/2}, PlotDot->False, DotStyle->{{Hue[0],PointSize[.02]}}, LineStyle->{Hue[0]}, CurveStyle->{Thickness[.008]}, AspectRatio->Automatic, PlotRange->{{-1.2,1.2},{-.2,.8}}]"; 


    InversionCircle::usage = 
      "InversionCircle is an option for ParaPlot. InversionCircle->{{x,y},r} plots the inversion of the curve with repect to  the circle with center {x,y} and radius r. Default is InversionCircle->None. Use DotStyle to control the rendering of dots.  What is Inversion of a curve? Given a curve C, and a circle with center M and radius r. Let P be a point on the curve. Let Q be a point colinear with M and P, and Q is a point such that MP * MQ == r^2. The locus of Q is called the inversion of the curve C with respect to the given circle. Example: (* Rose and Epi spiral, 20 sec.*) ParaPlot[{ Cos[3 t] Cos[t], Cos[3 t] Sin[t]}, {t, 0, Pi, Pi/120}, InversionCircle->{{0,0},1}, PlotDot->False, AspectRatio->Automatic]"; 


    PlotOsculatingCircle::usage = 
      "PlotOsculatingCircle is an option for ParaPlot. The default is PlotOsculatingCircle->False. Use LineStyle to control the rendering. Example:(* Equiangular Sprial, 48 sec. *) ParaPlot[ {1/4 E^(t Cot[1.4]) Cos[t], 1/4 E^(t Cot[1.4]) Sin[t] }, {t, 0, 4 Pi, 4 Pi/40}, PlotOsculatingCircle->True, LineStyle->{Hue[0]}, PlotRadial->True, PlotCurve->False, PlotDot->False, AspectRatio->Automatic]"; 


    PlotInvolute::usage = 
      "PlotInvolute is an option for ParaPlot. PlotInvolute->True will plot the involute of the given curve. Default is PlotInvolute->False. Use the option DotStyle and LineStyle to control rendering. Example: ParaPlot[{t,Sin@t}, {t, 0, 2 Pi, 2 Pi/80}, PlotInvolute->True, PlotDot->False,AspectRatio->Automatic]"; 


    PlotEvolute::usage = 
      "PlotEvolute is an option for ParaPlot. The default is PlotEvolute->False. Evolute of a curve is the locus of its center of curvature. Example: (* Tracktrix and Catenary, 20 sec. *) ParaPlot[{ Log[ Sec@t + Tan@t] -Sin@t, Cos@t}, {t, -1.53, 1.53,.1}, PlotEvolute->True, PlotRange->{{-3,3},{0,3}}, AspectRatio->Automatic]"; 


    PlotRadial::usage = 
      "PlotRadial is an option for ParaPlot. The default is PlotRadial->False. (*Radial of a curve is the locus of vectors defined by P2-P1, where P1 is any point on the curve and P2 is the center of curvature at P1.*) Example:(* Astroid and Rose, 36 sec.*) ParaPlot[ {(3 Cos[t])/4 + Cos[3 t]/4, (3 Sin[t])/4 - Sin[3 t]/4}, {t,0, 2 Pi, 2 Pi/100}, PlotRadial->True, PlotDot->False, LineStyle->{Hue[0]},DotStyle->{{Hue[.9], PointSize[.01]}}, AspectRatio->Automatic, Axes->False]"; \)

\(CurveColorFunction::usage = 
      "CurveColorFunction is an option for ParaPlot that specifies how the curve should be colored varing with the parameter t. CurveColorFunction->{myColorFunc} where myColorFunc must be a color directive pure function that can be mapped into a real number list between 0 and 1. Default is CurveColorFunction->{Hue[.65,#,.8]&}. Example:  (* Hypotrochoid, 26 sec.*) ParaPlot[ {(5 Cos[t])/8 + 0.1 Cos[(5 t)/3], (5 Sin[t])/8 - 0.1 Sin[(5 t)/3]}, {t, 0, 3 2 Pi}, CurveColorFunction->{Hue},CurveStyle->{Thickness[.015]}, PlotDot->False, PlotRange->All, AspectRatio->Automatic]"; 


    CurveStyle::usage = 
      "CurveStyle is an option for ParaPlot. You can use CurveStyle to control the rendering style of the curve except color. To specify color, use CurveColorFunction. Default is CurveStyle->{Thickness[0.005]}."; 


    DotStyle::usage = 
      "DotStyle is an option for ParaPlot. It specifies how dots generated by ParaPlot will be rendered (See ?TangentLineStyle for more detail) Example: ParaPlot[{Sin[t 2 Pi/12],Cos[t 2 Pi/12]}, {t, 0, 11}, Range[0,12], PlotParameterValue->True, DotStyle-> { {PointSize[.04],Hue[0]}, {PointSize[.02],Hue[.4,.8,.7]}, {PointSize[.02],Hue[.4,.8,.7]} }, PlotRange->All, AspectRatio->Automatic, Ticks->None]"; 


    LineStyle::usage = 
      "LineStyle is an option for ParaPlot. LineStyle -> style specifies that all lines or circles are to be generated with the specified graphics directive, or list of graphics directives. LineStyle -> {{style1}, {style2}, ... } specifies that successive lines generated should use graphics directives style1, style2,..."; 


    NormalLineStyle::usage = 
      "NormalLineStyle is an option for ParaPlot. It specifies how normal lines should be rendered. See ?LineStyle for similar usage."; 


    TangentLineStyle::usage = 
      "TangentLineStyle is an option for ParaPlot. It specifies how should tangent lines be rendered. See ?LineStyle for similar usage. Example: (* epitrochoid type curve, 45 sec.*) ParaPlot[ {Cos[t]+Cos[t/5] 4, Sin[t]+Sin[t/5] 4}, {t, 0, 9 Pi,.1}, TangentLineLength->6, PlotDot->False, PlotCurve->False, TangentLineStyle->Table[{Hue[i]},{i,0,1,.05}], AspectRatio->Automatic, PlotRange->All]"; 


    CausticLineStyle::usage\  = \ 
      "CausticLineStyle is an option for ParaPlot. It specifies how lines simulating light rays should be rendered. See ?LineStyle for similar usage."; 


    SecantLineStyle::usage = 
      "SecantLineStyle is an option for ParaPlot. It specifies how secant lines should be rendered. See ?LineStyle for similar usage."; \)

Begin private context

Begin["`Private`"]

Modules

NormalLineGP

NormalLineGP[tPointList_, velociVectorList_, ll_].
tPointlist is a list of points {{x1,y1},{x2,y2},...} representing the points of a parametric curve.
velociVectorList have the same form as tPointList. velociVectorList represents the velocity vector at those points. It's calculated by {xf'[ti],yf'[ti]}.
ll is a number representing a length.
NormalLineGP returns a list of the form {Line[{{a,b},{c,d}}]..}
these are lines normal to the curve at tPointList with length ll.

NormalLineGP[tPointList_, velociVectorList_, ll_] := 
  Module[{nVectorList}, nVectorList = 
     (If[#1 === {0, 0}, {0, 0}, 
         ({-Last[#1], First[#1]}*ll)/(Sqrt[First[#1]^2 + Last[#1]^2]*2.)] & 
) /@ velociVectorList; Line /@ 
     Transpose[{tPointList - nVectorList, tPointList + nVectorList}]]

TangentLineGP

TangentLineGP[tPointList_, velociVectorList_, ll_].
similiar to NormalLineGP.
TangentLineGP returns a list of the form {Line[{{a,b},{c,d}}]..} these are lines tangent to the curve at tPointList with length ll.

TangentLineGP[tPointList_, velociVectorList_, ll_] := 
	Module[	{tVectorList},
		tVectorList =
			If[	#==={0,0},
				{0,0},
				#/Sqrt[First[#]^2+Last[#]^2] ll/2.
			]& /@ velociVectorList;
		Line /@ Transpose@{ tPointList -tVectorList, tPointList +tVectorList}
	]

ParallelDotGP

ParallelDotGP[tPointList_, velociVectorList_, distList_].
similiar to NormalLineGP. distList is a list of number each representing a distance.
ParallelDotGP	returns a list of the form 
	{	{Point[{xa1,ya1}],Point[{xa2,ya2}],...},
			{Point[{xb1,yb1}], Point[{xb2,yb2}], ...},...
	}
	The ith list of points represents the curve parallel to the curve represented by tPointList, with distance distList[[i]].

ParallelDotGP[tPointList_, velociVectorList_, distList_] := 
	Module[	
		{nVectorList},
		nVectorList =
			If[	#==={0,0},
				{0,0},
				{-Last@#,First@#}/Sqrt[First[#]^2+Last[#]^2]
			]& /@ velociVectorList;
		nVectorList = (tPointList + nVectorList #)& /@ distList;
		Map[Point, nVectorList, {2}]
	]

VectorLength, UnitV, reflDirVector, CausticLineGP

VectorLength[] returns the length of a vector.

UnitV[] returns the unit vector.

reflDirVector[] returs a unit vector that is the ray vector {r1,r2} reflected off a wall vector {w1,w2}. The ray and wall vector do not have to be unit vectors, and if the wall is the zero vector, then zero vector is returned.

CatacousticLineGP[] returns a list of the form
	{	{Line[...],Line[...],...}. They represent rays from rayOrigin shooting towards the points on the parametric curve and reflected. Each line length is ll, including the reflected portion.

VectorLength[{x_,y_}]:= Sqrt[x^2+y^2]
UnitV[{x_,y_}]:= If[{x,y}=={0,0},{0,0},{x,y}/Sqrt[x^2+y^2]]

reflDirVector[{r1_,r2_},{w1_,w2_}]:=
	If[ {w1,w2}=={0,0}, {0,0},
		UnitV[-{r1,r2} + 2 ({w1,w2}.{r1,r2}/{w1,w2}.{w1,w2} {w1,w2})]
	]

CausticLineGP[points_, velociVectorList_, rayOrigin_,ll_]:=
	Module[{i,rayV, s, ll2 = Abs[ll]},
		s = Sign[ll];
		Table[
			rayV = points[[i]]-rayOrigin;
			If[ VectorLength[rayV] >= ll2,
				Line[{rayOrigin , rayOrigin + UnitV[rayV] ll2 }],
				Line[{rayOrigin, points[[i]],
					points[[i]] +
					reflDirVector[ rayV, velociVectorList[[i]] ] *
					(ll2 - VectorLength@rayV) * s
				}]
			], {i, Length@points}
		]
	]

SecantLineGP

SecantLineGP[ {{x1,y1},{x2,y2},..}, integer, integer] returns a list of the form {Line[{{a,b},{c,d}}], Line[],...}. These lines connect points given by the first argument. It will connect every (1+i*n)th point with (1+i*n+m)th point, where i starts from 0 (until there are no more points to connect).

SecantLineGP[ tPointList_, m_,n_] :=
	Line[{First@#,Last@#}]& /@ Partition[ tPointList, m+1, n]

ConchoidLineAndDotGP

ConchoidLineAndDotGP[point_, tPointList_, distList_].
returns a list of the form
{ {Line[..],Line[..],..}, {{Point[..],Point[..],..}, .. } }.
To see what are these, try
Show[Graphics[ ConchoidLineAndDotGP[{0,0},{{1,1},{2,1}},{-.5,.5,1}] ],Axes->True]

ConchoidLineAndDotGP[pointP_, tPointList_, distList_] := 
	Module[{ dirVList },
		dirVList = N@Map[ UnitV[#-pointP]&, N@tPointList];
		{
		Map[ Line,
			Transpose[
				{ tPointList+Min[distList] dirVList,
				tPointList+ Max[distList] dirVList}
			]
		],
		Map[ Point, Map[(tPointList + dirVList #)&, distList], {2}]
		}
	]

GetPedalPoint, PedalLineAndDotGP

PedalLineAndDotGP[pointP_, tPointList_, velociVectorList_].
returns a list of the form
{
	{Line[ { tPointList[[1]], pedalpoint1, pointP} ],
		Line[ { tPointList[[2]], pedalpoint3, pointP} ],
		Line[ { tPointList[[3]], pedalpoint3, pointP} ],
		...},
	{Point[pedalpoint1], Point[pedalpoint2], Point[pedalpoint3], ...}
}.

the three points inside Line[] makes a right angle, and (ti-pedalpointi) have the same direction as the ith part of velociVectorList.

GetPedalPoint[ {t1,t2}, {tp1,tp2}, {p1,p2}] return a point of the form {q1,q2} such that {q1,q2} == t {t1,t2} + {tp1,tp2} for some t, and
Dot[ {q1,q2}-{p1,p2}, {t1,t2}] == 0. Explaination: {t1,t2} represent a tangent vector of a curve at {tp1,tp2}.
{q1,q2} is a point on this tangent line such that {q1,q2} to {p1,p2} is perpendicular to it.

Older versions of GetPedalPoint.

GetPedalPoint[cT_, tp_, p_]:=
	Module[{},
		If[ cT==={0,0},
			{},
			First@LinearSolve[ Transpose[ {cT,{-Last@cT,First@cT}} ], (p-tp)] cT+tp
		]
	]

GetPedalPoint[cT_, tp_, p_]:=
	Module[{cT2 = UnitV[cT]},
		If[ cT2==={0,0}, {}, tp + (p - tp).cT2 cT2 ]
	]

PedalLineAndDotGP[pointP_, tPointList_, velociVectorList_] :=
	Module[ {pedalPointList},
		pedalPointList = 
			MapThread[
				GetPedalPoint[#1, #2, pointP]&,
				{velociVectorList, tPointList}
			];
		{	MapThread[
				If[ #2 === {}, {}, Line[{#1,#2,pointP}] ]&,
				{tPointList,pedalPointList}
			],
			Map[ If[ # === {}, {}, Point@#]& , pedalPointList]
		}
	]

InversionDotGP

InversionDotGP[{{x,y},r}, {{tx1,ty1},{tx2,ty2},...}]
returns a list of the form 
	{Point[...], Point[...], ...}

These points are the inverse of points {{tx1,ty1},{tx2,ty2},...} with respect to the circle {{x,y},r}.

definition of inverse:
Two points P and Q are mutually inverse with respect to a circle iff

dist[P-O] dist[Q-O] == r^2

where O is the center of the circle with radius r.

InversionDotGP[{center_, radius_}, tPointList_] := 
	Module[{ invPointList },
		invPointList =
			Map[
				(radius^2/VectorLength[#-center] *
				UnitV[#-center] + center)&,
				tPointList
			];
		Map[ Point, invPointList]
	]

InvoluteLineAndDotGP

InvoluteLineAndDotGP[ {xf@#&, yf@#&}, tList, curvePoints, velociVectors] will return a list of the form
{ {Line[..],Line[..],...}, {Point[..],Point[..],...} }.
Explaination of the arugments:
 {xf@#&, yf@#&} is the curve.
 tList is a list of the cuvrve's parameters.
 curvePoints have the form {{x1,y1},{x2,y2},...,{xn,yn}} that are points on the curve.
 velociVectors are the direction vector of the curve (i.e. {xf'@ti, yf'@ti} )
The list of graphic primitives returned represents the involute of the curve. The Point primitives is the involute of the curve at curvePoints, starting at
{x1, y1} going in the direction of the curve. The Line primitives connect these dots to curvePoints.

InvoluteLineAndDotGP[] uses UnitV[].

Clear[InvoluteLineAndDotGP]

InvoluteLineAndDotGP[ {xf_, yf_}, tList_, curvePoints_, velociVectors_]:=
	Module[{a,b,t,s,f,arcLengths, involutePoints},
		{a,b} = N@{First@tList,Last@tList};
		s =
			NDSolve[
				{	f'[t] == Sqrt[ (xf'@t)^2 + (yf'@t)^2 ],
					f@a == 0
				}, f, {t,a,b}
			][[1,1,2]];
		arcLengths = s /@ tList;
		involutePoints = arcLengths *(UnitV /@ -velociVectors) +curvePoints;
		{	MapThread[ Line[{#1,#2}]&,
				{curvePoints, involutePoints}
			],
			Point /@ involutePoints
		}
	]

k, curvatureGPs

k[ velociVectorList, acclVectorList] returns the list of real numbers that represent the curvature of a curve.

curvatureGPs[tPointList, velociVectorList, acclVectorList, {cir,evo,rad}]
returns a list of graphics primitives of the form
{
	{Circles[],..},
	{{Line[{{a,b},{c,d}}],..}, {Point[],..}},
	{{Line[{{e,f},{e,h}}],..}, {Point[],..}}
}
any of the list may be empty such as returning 
{ {}, { {}, {} }, { {}, {} } },
but it always have the same structure.
The first list are osculating circles, second are lines and points for evolutes, third list are lines and points for radials. Whether one of the three lists are empty depends whether True/False value given in {cir,evo,rad}.

k[ velociVectorList_, acclVectorList_]:=
	MapThread[
		If[ #1==={0,0} || #2==={0,0}, 0,
			Dot[ #2, {-Last@#1, First@#1}] / (Plus@@(#1^2))^(3/2)
		]&,
		{velociVectorList,acclVectorList}
	]

curvatureGPs[tPointList_, velociVectorList_, acclVectorList_,{cir_,evo_,rad_}] := 
	Module[  {normalUnitVList, radiusList, centerVectors, centerPoints},
		normalUnitVList =
			Map[
				If[	#==={0,0}, {0,0},
					{-Last@#,First@#}/Sqrt[First[#]^2+Last[#]^2] ]&
				, velociVectorList
			];
		radiusList = 1/k[velociVectorList, acclVectorList];
		centerVectors = normalUnitVList radiusList;
		centerPoints = centerVectors+ tPointList;
		{	If[	cir, 
				MapThread[ Circle[#1,#2]&, {centerPoints, Abs[radiusList]}]
				,{}
			],
			If[evo,
				{	MapThread[ Line[{#1,#2}]&, {tPointList, centerPoints}],
					Map[ Point, centerPoints ]
				},
				{{},{}}
			],
			If[rad,
				{	Map[ Line[{{0,0},#}]&, centerVectors],
					Map[ Point, centerVectors]
				},
				{{},{}}
			]
		}
	]

ColorLinesGP

ColorLinesGP::usage =
	"ColorLinesGP[Line[{{x1,y1},{x2,y2},...{xi,yi}}],(ColorFunc)] 
	returns a list of graphic primitive of the form
	{	{Hue[a1],Line[{{x1,y1},{x2,y2}}]},
		{Hue[a2],Line[{{x2,y2},{x3,y3}}]},
		...
		{Hue[a3],Line[{{x[i-1],y[j-1]},{xi,yj}}]}	}., 
		where Hue[ai] is an example output of ColorFunc.
	ColorFunc must be a color directive such as Hue that can be mapped to a list
	of real numbers from 0 to 1.";

ColorLinesGP[ lineGP_Line, colorf_:(Hue[.7,#,.8]&) ] :=
	Transpose@{
		colorf /@ Range[0,1,1/(Length@@lineGP-2)],
		Line/@Partition[ First@lineGP, 2, 1]
	}

StyleInjector

StyleInjector[listA, listB] will pair the elements of these two lists. If listB is longer than listA, then the rest of listB are dropped. If listB is shorter, then listB will "reused" starting with its first element to match the number of elements in listA. This "resued" will be cycled utill there's enough elements. Also, each member of listB will be flattened before being paired with elements in listA. For example, listA = {1,2,3,..}, listB = {{a1,a2},b,c,d,...}, then the result will be {{a1,a2,1},{b,2},{c,3},...}, not
{{ {a1,a2} ,1},{b,2},{c,3},...}. When the length of styleList is 0 or 1, special methods are used to save time.

Old implimentation:
StyleInjector[ GPlist_, styleList_]:=
	Table[
		Append[
			Flatten@{ First@RotateLeft[styleList,t-1] },
			GPlist[[t]]
		],
		{t, Length@GPlist}
	]

StyleInjector[GPlist_, styleList_] :=
	Which[
		styleList==={},
		GPlist,
		Length@styleList === 1,
		Flatten@{styleList,GPlist},
		True,
		Flatten /@ Transpose[{
			Take[
				Join @@	
					Table[ styleList, {Ceiling[ Length@GPlist/Length@styleList]} ],
				Length@GPlist
			],
			GPlist
		}]
	]

Main Body of ArcLengthPartiton

ArcLengthPartition[ parametrizedCurve_Function, {tmin_, tmax_}, n_ ]:=
	Module[ {a,b,s,f,t},
		{a,b} = N@{tmin,tmax};
		s = NDSolve[
			{	f'[t] == Sqrt[Plus@@(parametrizedCurve'[t]^2)],
				f@a == 0
			}, f, {t,a,b}
		][[1,1,2]];
		t /. FindRoot[ s@t == #, {t,{a,b}}]& /@ Range[0, s@b, s@b/n]
	]

ArcLengthPartition[{exprX_, exprY_}, {t_Symbol, tmin_, tmax_}, n_] :=
	ArcLengthPartition[ Function[{t},{exprX, exprY}], {tmin, tmax}, n
	]/; NumberQ[N@tmin] && NumberQ[N@tmax] && NumberQ@N@n

Modifying Plot and ParametricPlot to avoid asymptotes

Plot::usage = "
	Plot[f, {x, xmin, xmax}] generates a plot of f as a function of
	x from xmin to xmax.
	Plot[f, {x, xmin, x1, x2,..., xmax}] avoids plotting
	asymptotes at singularities x1, x2,...
	Plot[{f1, f2, ...}, {x, xmin, xmax}] plots several functions fi.";

Unprotect[Plot]
Plot[ f_, {x_, a_, lims__, b_}, opts___] :=
	Module[{dfun, tmp, d},
		dfun = DisplayFunction /. {opts} /. Options[Plot];
		d = (Abs[a]+Abs[b]) $MachineEpsilon 10;
		tmp = Partition[{a,lims, b}, 2, 1];
		tmp = Map[ (# +{d,-d}) &, tmp];
		tmp = Map[
			Plot[ f, Evaluate@ Prepend[#,x],
				DisplayFunction->Identity, opts
			]&,
			tmp
		];
		Show[ tmp, DisplayFunction->dfun]
	]
Protect[Plot]

ParametricPlot::usage = "
	ParametricPlot[{fx, fy}, {t, tmin, tmax}] produces a parametric plot with x
	and y coordinates fx and fy generated as a function of t.
	ParametricPlot[{fx, fy}, {t, tmin, t1, t2,..., tmax}] avoids plotting
	asymptotes at singularities t1, t2...
	ParametricPlot[{{fx, fy}, {gx, gy}, ...}, {t, tmin, tmax}] plots several
	parametric curves.";

Unprotect[ParametricPlot]

ParametricPlot[ f_, {x_, a_, lims__, b_}, opts___] :=
	Module[{dfun, tmp, d},
		dfun = DisplayFunction /. {opts} /. Options[Plot];
		d = (Abs[a]+Abs[b]) $MachineEpsilon 10;
		tmp = Partition[{a,lims, b}, 2, 1];
		tmp = Map[ (#+{d,-d}) &, tmp];
		tmp = Map[
			ParametricPlot[ f, Evaluate@ Prepend[#,x],
				DisplayFunction->Identity, opts
			]&,
			tmp
		];
		Show[ tmp, DisplayFunction->dfun]
	]

Protect[ParametricPlot]

Main Body of ParaPlot

Options[ParaPlot] = 
	Join[
		{
		PlotCurve->True,
		PlotDot->True,
		PlotParameterValue->False,
		NormalLineLength->0,
		TangentLineLength->0,
		CausticLineLength->0,
		CausticOrigin->{0,0},
		SecantConnection->{1,1},
		ParallelCurveOffset->{0},
		ConchoidSetting->{{0,0},{0}},
		PedalPoint->None,
		InversionCircle->None,
		PlotOsculatingCircle->False,
		PlotInvolute->False,
		PlotEvolute->False,
		PlotRadial->False,
		CurveColorFunction->{Hue[.65,#,.8]&},
		CurveStyle->{Thickness[0.005]},
		DotStyle->{{ Hue[0],PointSize[.01]}},
		LineStyle->{{Hue[.18],Thickness[.004]}},
		NormalLineStyle->{{Hue[.6],Thickness[.004]}},
		TangentLineStyle->{{Hue[0],Thickness[.004]}},
		SecantLineStyle->{{Hue[0],Thickness[.004]}},
		CausticLineStyle->{{Hue[.5],Thickness[.004]}}
		},
		Options[ParametricPlot]
	];

Programmer's documentation about ParaPlot[].

The code for ParaPlot is very straightforward to the point that no documentation is necessary. This is a highlevel outline.

What ParaPlot does in terms of its function:
ParaPlot is similar to ParametricPlot, except it adds several options to plot extra lines and points related to the given curve. (these extra lines and curves are mathematically defined from the given curve, such as evolute, involute, pedal,...etc) Beside extra lines and points, ParaPlot also renders the given curve in varing color according to the parameter t, and render Points on the curve with Text showing the value of parameter at the point.

How ParaPlot works:
First, ParaPlot gets all the options that determine whether to plot extra lines and points (will be called Feature Graphics from now on).
Each Feature Graphics have one or more local variable inside ParaPlot that ends with GP. (e.g. normalLineGP, involuteLineGP, involutePointGP) Each feature graphics also have a module outside ParaPlot, e.g. NormalLineGP[], InvoluteLineAndDotGP[]. ***These modules ALWAYS return a list of Graphics Primitives.***

If the option is set to plot Feature Graphics, PlotInvolute->True, for example, ParaPlot calls a module for that feature and assign the output of the module to the variable. For example,
{involuteLineGP, involutePointGP} =
If[ pInvolute === False, {{},{}},
	InvoluteLineAndDotGP[{xf, yf},tList,tPointList,velociVectorList]
]; 

Feature Graphics are always computed by calling the corresponding module outside ParaPlot. In no where the computation is carried inside ParaPlot.

This process is done for every Feature Graphics variable xxxGP inside ParaPlot. So now we have a set of xxxGPs, each is a list of graphic primitives (the list may be empty).

Now, these xxxGP get assigned graphics directive, according to default or user specification, by xxxGP = StyleInjector[xxxGP, xxxStyle].

After that, the local variable curveGP that stands for the parametric curve itself get assigned from the primitives extracted from ParametricPlot, along with graphic directive embedded.

Lastly, ParaPlot uses Show to show all the xxxGPs and curveGP. And, also added inside Show are some of the extra features appropriate for some Feature Graphics, such as adding a Point primitive at the Pedal point.

ParaPlot[{xf_Function,yf_Function},
	{tmin_,tmax_, dt_:Automatic}, tlist_List:{Automatic}, opts___Rule
]:=
	Module[{
		pCurve, pDots, ppValue, nll,tll,cll,cOrigin,
		secc, plcOffset, concSetting, pedalP, invCircle, 
		pOCircle,pInvolute, pEvolute, pRadial,
		ccFunction, cStyle, dStyle,lStyle, nlStyle,tlStyle,clStyle,slStyle,
		t, tMin, tMax, ndt, tList, tPointList, velociVectorList, acclVectorList,
		tDotGP, tTextGP, normalLineGP, tangentLineGP, causticLineGP,
		secantLineGP, parallPointGP, concoidLineGP, concoidPointGP,
		pedalLineGP, pedalPointGP, inversPointGP,
		involuteLineGP, involutePointGP,
		oscCircleGP, evoluteLineGP, evolutePointGP,radialLineGP, radialPointGP,
		curveGP},
		
		Off[Power::infy, Infinity::indet, Graphics::gptn];
		
		pCurve = PlotCurve  /. {opts} /. Options[ParaPlot];
		pDots = PlotDot /. {opts} /. Options[ParaPlot];
		ppValue = PlotParameterValue /. {opts} /. Options[ParaPlot];
		nll = NormalLineLength /. {opts} /. Options[ParaPlot];
		tll = TangentLineLength /. {opts} /. Options[ParaPlot];
		cll = CausticLineLength /. {opts} /. Options[ParaPlot];
		cOrigin = CausticOrigin /. {opts} /. Options[ParaPlot];
		secc = SecantConnection /. {opts} /. Options[ParaPlot];
		plcOffset = ParallelCurveOffset /. {opts} /. Options[ParaPlot];
		concSetting = ConchoidSetting /. {opts} /. Options[ParaPlot];
		pedalP = PedalPoint /. {opts} /. Options[ParaPlot];
		invCircle = InversionCircle /. {opts} /. Options[ParaPlot];
		pOCircle = PlotOsculatingCircle /. {opts} /. Options[ParaPlot];
		pInvolute = PlotInvolute /. {opts} /. Options[ParaPlot];
		pEvolute = PlotEvolute /. {opts} /. Options[ParaPlot];
		pRadial = PlotRadial /. {opts} /. Options[ParaPlot];

		ccFunction = CurveColorFunction /. {opts} /. Options[ParaPlot];
		cStyle = CurveStyle /. {opts} /. Options[ParaPlot];
		dStyle = DotStyle /. {opts} /. Options[ParaPlot];
		lStyle = LineStyle /. {opts} /. Options[ParaPlot];
		nlStyle = NormalLineStyle /. {opts} /. Options[ParaPlot];
		tlStyle = TangentLineStyle /. {opts} /. Options[ParaPlot];
		clStyle = CausticLineStyle /. {opts} /. Options[ParaPlot];
		slStyle = SecantLineStyle /. {opts} /. Options[ParaPlot];

(*	these are just for the convenience of the user. For example, if the user
	typed CausticLineStyle->Hue[.0], it will be converted to the right syntax
	{Hue[0]}.
*)
		If[ Not[ Head[ccFunction] === List], ccFunction = {ccFunction}];
		If[ Not[ Head[cStyle] === List], cStyle = {cStyle}];
		If[ Not[ Head[dStyle] === List], dStyle = {dStyle}];
		If[ Not[ Head[lStyle] === List], lStyle = {lStyle}];
		If[ Not[ Head[nlStyle] === List], nlStyle = {nlStyle}];
		If[ Not[ Head[tlStyle] === List], tlStyle = {tlStyle}];
		If[ Not[ Head[tlStyle] === List], clStyle = {clStyle}];
		If[ Not[ Head[tlStyle] === List], slStyle = {slStyle}];

(*	tList is a list of t values.
	velociVectorList is a list of the velocity vector of the curve at tList.
	acclVectorList is the accelation vector list of the curve at tList.
	Both are not normalized.
*)

		{tMin,tMax} = N[{tmin,tmax}];
		ndt = If[	dt===Automatic,	(tMax-tMin)/4., N@dt];
		tList = If[ tlist==={Automatic}, Range[tMin,tMax,ndt], N@tlist];
		tPointList = N[ {xf[#],yf[#]}& /@ tList ];
		If[	0 === nll === tll === cll && plcOffset==={0} &&
			None === pedalP &&
			False === pOCircle === pInvolute ===pEvolute === pRadial,
			{velociVectorList, acclVectorList} = {{},{}},
			velociVectorList = N[{xf'[#],yf'[#]}& /@ tList];
				If[ pOCircle || pEvolute || pRadial,
					acclVectorList = N[{xf''[#], yf''[#]}& /@ tList],
					acclVectorList = {}
				]
		];

(*	below is a bunch of assignments of local variable ending with GP.
	Each xxxGP is a (list of) graphic primitive
	that represents a special feature to be plotted.
	If the option to plot them is turned off, they get assigend {}.
	Otherwise, for most of them, information are passed to modules, and these
	modules return the appropriate GP. These
	modules/functions also ends with GP, in that they return (a list of)
	graphic primitives.
	At the end of the program, these xxxGP are put inside Show[].
*)

 		tTextGP = 
			If[ ppValue === True,
				Table[
					Text[ NumberForm[ tList[[t]], 4], tPointList[[t]], {-2,-1}],
					{t,1,Length@tList}
				],
 				{}
			];
		tDotGP = If[ pDots === True, Point/@tPointList , {}];
		normalLineGP = If[ nll===0,{}, NormalLineGP[tPointList,velociVectorList,nll] ];
		tangentLineGP = If[ tll===0,{}, TangentLineGP[tPointList,velociVectorList,tll] ];
		causticLineGP =
			If[ cll===0,{},
				CausticLineGP[tPointList,velociVectorList,N@cOrigin,N@cll]
			];
		secantLineGP = If[ secc==={1,1},{},
						SecantLineGP[tPointList,First@secc,Last@secc] ];	
		parallPointGP = If[ plcOffset==={0},{},
						ParallelDotGP[tPointList,velociVectorList,plcOffset] ];
		{concoidLineGP, concoidPointGP} =
			If[ Last@concSetting==={0},{{},{}},
				ConchoidLineAndDotGP[ First@concSetting,
						tPointList, Last@concSetting]
			];
		{pedalLineGP, pedalPointGP} =
			If[	pedalP === None, {{},{}},
				PedalLineAndDotGP[pedalP,tPointList,velociVectorList]
			];

		inversPointGP =
			If[	invCircle === None, {},
				InversionDotGP[ invCircle, tPointList]
			];
		
		{involuteLineGP, involutePointGP} =
			If[ pInvolute === False, {{},{}},
				InvoluteLineAndDotGP[{xf, yf},tList,tPointList,velociVectorList]
			];
		
		{oscCircleGP, 
		{ evoluteLineGP, evolutePointGP},
		{ radialLineGP, radialPointGP} } = 
			If[ acclVectorList === {},
				{{},{{},{}},{{},{}}},
				curvatureGPs[ tPointList, velociVectorList, acclVectorList,
					{ pOCircle, pEvolute, pRadial}]
			];

(*	add graphic directives to these GP
*)
		tDotGP = StyleInjector[tDotGP, dStyle];
 		normalLineGP = StyleInjector[normalLineGP, nlStyle];
		tangentLineGP = StyleInjector[tangentLineGP, tlStyle];
		causticLineGP = StyleInjector[causticLineGP, clStyle];
		secantLineGP = StyleInjector[secantLineGP, slStyle];
		parallPointGP = StyleInjector[parallPointGP, dStyle];
		concoidLineGP = StyleInjector[concoidLineGP, lStyle];
		concoidPointGP = StyleInjector[concoidPointGP, dStyle];
		pedalLineGP = StyleInjector[pedalLineGP, lStyle];
		pedalPointGP = StyleInjector[pedalPointGP, dStyle];
		inversPointGP = StyleInjector[inversPointGP, dStyle];
		involuteLineGP = StyleInjector[involuteLineGP, lStyle];
		involutePointGP = StyleInjector[involutePointGP, dStyle];
		oscCircleGP = StyleInjector[oscCircleGP, lStyle];
		evoluteLineGP = StyleInjector[evoluteLineGP, lStyle];
		evolutePointGP = StyleInjector[evolutePointGP, dStyle];
		radialLineGP = StyleInjector[radialLineGP, lStyle];
		radialPointGP = StyleInjector[radialPointGP, dStyle];

(*	curveGP is the graphic primitive for the curve.
	ColorLinesGP is used to add graphic directives so the color of
	the curve varies with the parameter
*)
		curveGP = 
		If[ pCurve === True,
			Flatten[{cStyle,
				ColorLinesGP[
					First@Cases[
						ParametricPlot[ {xf[t], yf[t]},
							{t, tMin, tMax }, 
							DisplayFunction->Identity,
							Evaluate@FilterOptions[ParametricPlot,opts]
						]
						, Line[x__],
						Infinity
					],
					First@ccFunction
				]
			}],
			{}
		];	

(*	Besides showing all the GPs, some extra GP are added that represents some
	special points related to a specific feature. For example, a point is added
	that represents the caustic origin. If a specific feature/option is on,
	the related extra GP (if there's any) will be drawn.
	User have no control over their existance or appearance. But of course,
	advanced users can always delete them after from the output.
	The DeleteCases[] is to get rid of list of graphics directives that
	does not contain any graphic primitives.
*)
		(On[ Power::infy, Infinity::indet, Graphics::gptn]; #)& @
		Show@ Graphics[
			DeleteCases[
				{ radialLineGP, oscCircleGP, involuteLineGP, evoluteLineGP,
				tangentLineGP, normalLineGP, secantLineGP,
				causticLineGP, concoidLineGP, pedalLineGP,
				curveGP,
				involutePointGP, evolutePointGP, radialPointGP,
				parallPointGP, concoidPointGP,
				pedalPointGP,
				If[ invCircle===None, {}, {Hue[.18], Circle@@invCircle }],
				inversPointGP, tDotGP, tTextGP,
				If[ cll===0, {}, {Hue[0], PointSize[.02],Point[cOrigin]}],
				If[ Last@concSetting==={0}, {},
					{Hue[.7,.9,.8],PointSize[.02],Point[First@concSetting]}
				],
				If[ pedalP===None, {},
					{Hue[.7,.9,.8],PointSize[.02],Point[pedalP]}
				]
				},
				{(_Hue|_PointSize|_Thickness|_CMYKColor|_RGBColor|_GrayLevel)...}
			],
			FilterOptions[Graphics,opts], Axes->True
		]
	]/; NumberQ[N@tmin] && NumberQ[N@tmax] && (NumberQ[N@dt] || SameQ[dt,Automatic])

ParaPlot[
	curve_?VectorQ,{t_Symbol, tmin_ ,tmax_ , dt_:Automatic},
	tlist_List:{Automatic},opts___Rule
]:= ParaPlot[
		{Function[t, Evaluate@ First@ curve], Function[t, Evaluate@ Last@ curve]},
		{tmin,tmax, dt},tlist,opts
	]/; NumberQ[N@tmin] &&
		NumberQ[N@tmax] &&
		(NumberQ[N@dt] || SameQ[dt,Automatic])

ParaPlot[
	curves_?MatrixQ, {t_Symbol, tmin_ ,tmax_ , dt_:Automatic},
	tlist_List:{Automatic},opts___Rule
]:=
	Identity[
		Off[Power::infy, Infinity::indet, Graphics::gptn];
		(On[Power::infy, Infinity::indet, Graphics::gptn]; #)& @
		ParametricPlot[ curves, {t, tmin, tmax},
			Evaluate@ FilterOptions[ ParametricPlot, opts]
		]
	]/; NumberQ[N@tmin] &&
		NumberQ[N@tmax] &&
		(NumberQ[N@dt] || SameQ[dt,Automatic])

Main Body of ParaPolarPlot

ParaPolarPlot[{distExpr_, angleExpr_}, range_List, rest___] = 
      ParaPlot[distExpr {Cos[angleExpr], Sin[angleExpr]}, range, rest];

End, Protect, EndPackage

End[]Protect[ArcLengthPartition, ParaPlot, ParaPolarPlot]EndPackage[]