@c polygon.texi

@c This file is part of the 3DLDF User and Reference Manual.
@c Copyright (C) 2003, 2004 Laurence D. Finston 
@c See the section "GNU Free Documentation License" in the file 
@c fdl.texi for copying conditions.

@c $Id: polygon.texi,v 1.6 2004/01/12 18:40:29 lfinsto1 Exp lfinsto1 $
 
@node Polygon Reference, Regular Polygon Reference, Path Reference, Top
@chapter Polygon Reference 

@tindex Polygon
Class @code{Polygon} is defined in @file{polygons.web}, and
is derived from @code{Path}, using public derivation.

@code{Polygon} is mainly intended for use as a base class for more
specialized kinds of polygons.  Currently, the classes
@code{Reg_Polygon} (regular polygon) and @code{Rectangle} are defined.
@xref{Regular Polygon Reference}, and @ref{Rectangle Reference}.

@menu
* Polygon Data Members::        
* Polygon Operators::           
* Querying Polygons::           
* Affine Transformations for Polygons::  
* Polygon Intersections::       
@end menu
 
@node Polygon Data Members, Polygon Operators, Polygon Reference, Polygon Reference
@section Data Members

@deftypevr {Private variable} Point center
The center of the @code{Polygon}, if it has one.  However, a
@code{Polygon} need not have a @code{center}.  If it doesn't,
@code{center} should be set to @code{INVALID_POINT}.  
@end deftypevr 

@node Polygon Operators, Querying Polygons, Polygon Data Members, Polygon Reference
@section Operators
@deftypefn {Virtual operator} Transform operator*= (const Transform& @var{t})
Multiplies a @code{Polygon} by the @code{Transform} @var{t}.  
Similar to @code{Path::operator*=(const Transform& t)}, except that 
@code{center} is transformed as well.  
@xref{Path Operators,,Path Reference; Operators}. 
@end deftypefn 

@node Querying Polygons, Affine Transformations for Polygons, Polygon Operators, Polygon Reference
@section Querying 

@deftypefn {Virtual function} {const Point&} get_center (void) 
@deftypefnx {@code{const} function} Point get_center (void)
These functions return @code{center}.  If the @code{Polygon} doesn't
contain any @code{Points}, a warning is issued, and @code{INVALID_POINT}
is returned.
@end deftypefn 

@node Affine Transformations for Polygons, Polygon Intersections, Querying Polygons, Polygon Reference
@section Affine Transformations
  
@deftypefn {Virtual function} Transform rotate ({const real} @var{x}, [{const real} @var{y} = 0, [{const real} @var{z} = 0]])
@deftypefnx {Virtual function} Transform rotate ({const Point&} @var{p0}, {const Point&} @var{p1}, [{const real} @var{angle} = 180])
@deftypefnx {Virtual function} Transform rotate ({const Path&} @var{p}, [{const real} @var{angle} = 180])
@deftypefnx {Virtual function} Transform scale (real @var{x}, [real @var{y} = 1, [real @var{z} = 1]])
@deftypefnx {Virtual function} Transform shear (real @var{xy}, [real @var{xz} = 0, [real @var{yx} = 0, [real @var{yz} = 0, [real @var{zx} = 0, [real @var{zy} = 0]]]]])
@deftypefnx {Virtual function} Transform shift (real @var{x}, [real @var{y} = 0, [real @var{z} = 0]])
@deftypefnx {Virtual function} Transform shift ({const Point&} @var{p})
@deftypefnx {Virtual function} void shift_times (real @var{x}, [real @var{y} = 1, [real @var{z} = 1]])
@deftypefnx {Virtual function} void shift_times ({const Point&} @var{p})
@c
The affine transformation functions for @code{Polygon} differ from the
@code{Path} versions only in that @code{center} is transformed as well. 
@xref{Affine Transformations for Paths,,Path Reference; Affine Transformations}.

Please note, that the classes currently derived from @code{Polygon},
namely @code{Reg_Polygon} and @code{Rectangle}, currently inherit these
functions from @code{Polygon}.  The problem with this is, that they have 
data members, which are not recalculated when a @code{Reg_Polygon} or
@code{Rectangle} is transformed.  I plan to do something about this soon!
It will also be necessary to add the function 
@code{Reg_Polygon::is_reg_polygonal()}, in order to test whether operations
on a @code{Reg_Polygon} have caused it to become
irregular and/or non-polygonal.  Similarly, the function
@code{Rectangle::is_rectangular()} must be added, to test whether
operations on a @code{Rectangle} has caused it to become
non-rectangular.
@xref{Regular Polygon Data Members,,Regular Polygon Reference; 
Data Members}, and @ref{Rectangle Data Members,,Rectangle Reference;
Data Members}.
@end deftypefn 

@node Polygon Intersections,  , Affine Transformations for Polygons, Polygon Reference
@section Intersections
@deftypefn {@code{const} function} bool_point_pair intersection_points ({const Point&} @var{p0}, {const Point&} @var{p1})
@deftypefnx {@code{const} function} bool_point_pair intersection_points ({const Path&} @var{p})
@c
These functions find the intersections of the
@code{Polygon} and a line.
In the first version, the @code{Point} arguments are the end points of
the line.  The argument to the second version must be a linear
@code{Path}. 

A line and a regular polygon or rectangle@c
@c
@footnote{@code{Reg_Polygon} and @code{Rectangle} are currently the only
classes derived from @code{Polygon}.} 
@c
can intersect at two points at most.  
Let @code{b} be a @code{bool_point_pair} returned by
@code{intersection_points()}.  
If no
intersection points are found, @code{b.first.pt} and @code{b.second.pt}
will be @code{INVALID_POINT}, and @code{b.first.b} and @code{b.second.b}
will be @code{false}.  If a single intersection point is found, the
corresponding @code{Point} will be stored in @code{b.first.pt}.  If the
@code{Point} is on the line segment 
@OVERRTARROW{p_0p_1}, 
@code{b.first.b} will be @code{true},
otherwise @code{false}.  If a second intersection point is found, it
will be stored in @code{b.second.pt}, and @code{b.second.b} is set
analogously to @code{b.first.b}.  

When the @code{Point} arguments and the @code{Reg_Polygon} are coplanar,
as in @NEXTFIG{}, two intersection points are possible.  In this case,
only intersection points of the line with an edge of the
@code{Reg_Polygon} are returned in the @code{bool_point_pair}.

@example
Point A(1, 1, 1);
Reg_Polygon r(origin, 5, 3);
Transform t;
t.rotate(15, 12, 11);
t.shift(A);
Point P(-2, 0, -1);
Point Q(2, 0, 1);
P *= Q *= r *= t;
bool_point_pair bpp = r.intersection_points(P, Q);
bpp.first.pt.dotlabel("$f$", "rt"); 
bpp.second.pt.dotlabel("$s$"); 
@end example

@c
@iftex
@tex
\ifmakeexamples
\BEX
\BGRP
\immediate\write\examples{default_focus.set(2, 10, -10, 2, 10, 10, 10);}
\immediate\write\examples{Point A(1, 1, 1);}
\immediate\write\examples{Reg_Polygon r(origin, 5, 3);}
\immediate\write\examples{Transform t;}
\immediate\write\examples{t.rotate(15, 12, 11);}
\immediate\write\examples{t.shift(A);}
\immediate\write\examples{Point P(-2, 0, -1);}
\immediate\write\examples{Point Q(2, 0, 1);}
\immediate\write\examples{P *= Q *= r *= t;}
\immediate\write\examples{P.dotlabel("$P$"); }
\immediate\write\examples{Q.dotlabel("$Q$"); }
\immediate\write\examples{P.draw(Q);}
\immediate\write\examples{r.draw();}
\immediate\write\examples{bool_point_pair bpp = r.intersection_points(P, Q);}
\immediate\write\examples{bpp.first.pt.dotlabel("$f$", "rt"); }
\immediate\write\examples{bpp.second.pt.dotlabel("$s$"); }
\OEX{}
\EGRP
\EEX 1
\fi
\PEX
@end tex
@end iftex

@ifhtml
@html
<p align="center">
<br>
<img src="./graphics/png/3DLDFmp.139.png"
alt="[Figure 139. Not displayed.]"
/>
<br>
<br>
Fig. 139.
<br>
</p>
@end html
@end ifhtml

@ifinfo
[Figure 139 not displayed.]
@end ifinfo

@c


In @NEXTFIG{}, the lines @OVERRTARROW{BC} and 
@OVERRTARROW{PQ}
are not coplanar with the @code{Reg_Polygon} @math{r}.  In each case, only
one intersection point is possible, and it can be either an intersection
with an edge of the 
@code{Reg_Polygon}, or lie within its perimeter.


@example
Point B(r.get_point(3).mediate(r.get_point(4)));
Point C(B);
B.shift(0, 2, .5);
C.shift(0, -2, -.5);
Point P(-1, -2, -1);
Point Q(0, 2, 1);
B *= C *= P *= Q *= r *= t;
bool_point_pair bpp = r.intersection_points(B, C);
bpp.first.pt.dotlabel("$i_0$", "rt"); 
bpp = r.intersection_points(P, Q);
bpp.first.pt.dotlabel("$i_1$", "rt"); 
@end example

@c
@iftex
@tex
\ifmakeexamples
\BEX
\BGRP
\immediate\write\examples{default_focus.set(2, 10, -10, 2, 10, 10, 10);}
\immediate\write\examples{Point A(1, 1, 1);}
\immediate\write\examples{Reg_Polygon r(origin, 5, 3);}
\immediate\write\examples{Transform t;}
\immediate\write\examples{t.rotate(15, 12, 11);}
\immediate\write\examples{t.shift(A);}
\immediate\write\examples{Point B(r.get_point(3).mediate(r.get_point(4)));}
\immediate\write\examples{Point C(B);}
\immediate\write\examples{B.shift(0, 2, .5);}
\immediate\write\examples{C.shift(0, -2, -.5);}
\immediate\write\examples{Point P(-1, -2, -1);}
\immediate\write\examples{Point Q(0, 2, 1);}
\immediate\write\examples{B *= C *= P *= Q *= r *= t;}
\immediate\write\examples{B.dotlabel("$B$"); }
\immediate\write\examples{C.dotlabel("$C$", "bot"); }
\immediate\write\examples{B.draw(C);}
\immediate\write\examples{r.draw();}
\immediate\write\examples{P.dotlabel("$P$", "bot"); }
\immediate\write\examples{Q.dotlabel("$Q$"); }
\immediate\write\examples{P.draw(Q);}
\immediate\write\examples{bool_point_pair bpp = r.intersection_points(B, C);}
\immediate\write\examples{bpp.first.pt.dotlabel("$i_0$", "rt"); }
\immediate\write\examples{bpp = r.intersection_points(P, Q);}
\immediate\write\examples{bpp.first.pt.dotlabel("$i_1$", "rt"); }
\OEX{}
\EGRP
\EEX 1
\fi
\PEX
@end tex
@end iftex

@ifhtml
@html
<p align="center">
<br>
<img src="./graphics/png/3DLDFmp.140.png"
alt="[Figure 140. Not displayed.]"
/>
<br>
<br>
Fig. 140.
<br>
</p>
@end html
@end ifhtml

@ifinfo
[Figure 140 not displayed.]
@end ifinfo

@c


In @NEXTFIG{}, the intersection point of @math{r} with the line
@OVERRTARROW{PQ}
does not lie on the line @emph{segment} @math{PQ}. 

@example
bpp = r.intersection_points(P, Q);
bpp.first.pt.dotlabel("$i$", "rt");
cout << "bpp.first.b == " << bpp.first.b << endl << flush;
@print{} bpp.first.b == 0
@end example


@c
@iftex
@tex
\ifmakeexamples
\BEX
\BGRP 
\immediate\write\examples{default_focus.set(2, 10, -10, 2, 10, 10, 10);}
\immediate\write\examples{Point A(1, 1, 1);}
\immediate\write\examples{Reg_Polygon r(origin, 5, 3);}
\immediate\write\examples{Transform t;}
\immediate\write\examples{t.rotate(10, 0, 60);}
\immediate\write\examples{t.shift(A);}
\immediate\write\examples{Point P(0, 1);}
\immediate\write\examples{Point Q(0, 3);}
\immediate\write\examples{P *= Q *= r *= t;}
\immediate\write\examples{r.draw();}
\immediate\write\examples{P.dotlabel("$P$"); }
\immediate\write\examples{Q.dotlabel("$Q$"); }
\immediate\write\examples{P.draw(Q);}
\immediate\write\examples{bool_point_pair bpp = r.intersection_points(P, Q);}
\immediate\write\examples{bpp.first.pt.dotlabel("$i$"); }
\immediate\write\examples{Point S(P.mediate(bpp.first.pt, 2.25));}
\immediate\write\examples{P.draw(S, black, "evenly");}
\OEX{}
\EGRP
\EEX 1
\fi
\PEX
@end tex
@end iftex

@ifhtml
@html
<p align="center">
<br>
<img src="./graphics/png/3DLDFmp.141.png"
alt="[Figure 141. Not displayed.]"
/>
<br>
<br>
Fig. 141.
<br>
</p>
@end html
@end ifhtml

@ifinfo
[Figure 141 not displayed.]
@end ifinfo

@c


@end deftypefn 


@deftypefn {@code{const} function} {vector<Point>} intersection_points ({const Polygon&} @var{r})
Finds the intersection points of two @code{Polygons}.  
Let @math{v} be the @code{vector<Point>} returned by
@code{intersection_points()}.  If the @code{Polygons} are coplanar, 
@math{v}
will contain the intersection points of the edges of the
@code{Polygons}, as in @NEXTFIG{}.

@example
Rectangle r(origin, 4, 4);
Reg_Polygon rp(origin, 5, 5, 0, 36);
rp.shift(0, 0, .25);
vector <Point> v = r.intersection_points(rp);
@end example


@c
@iftex
@tex
\ifmakeexamples
\BEX
\BGRP
\immediate\write\examples{Rectangle r(origin, 4, 4);}
\immediate\write\examples{Reg_Polygon rp(origin, 5, 5, 0, 36);}
\immediate\write\examples{rp.shift(0, 0, .25);}
\immediate\write\examples{r.draw();}
\immediate\write\examples{rp.draw();}
\immediate\write\examples{vector <Point> v = r.intersection_points(rp);}
\immediate\write\examples{v[0].dotlabel(0, "llft"); }
\immediate\write\examples{v[1].dotlabel(1, "lrt"); }
\immediate\write\examples{v[2].dotlabel(2, "lrt"); }
\immediate\write\examples{v[3].dotlabel(3, "rt"); }
\immediate\write\examples{v[4].dotlabel(4, "ulft"); }
\immediate\write\examples{v[5].dotlabel(5, "urt"); }
\immediate\write\examples{v[6].dotlabel(6, "lft"); }
\immediate\write\examples{v[7].dotlabel(7, "llft"); }
\OEX{Projections::PARALLEL_X_Z}
\EGRP
\EEX 1
\fi
\PEX
@end tex
@end iftex

@ifhtml
@html
<p align="center">
<br>
<img src="./graphics/png/3DLDFmp.142.png"
alt="[Figure 142. Not displayed.]"
/>
<br>
<br>
Fig. 142.
<br>
</p>
@end html
@end ifhtml

@ifinfo
[Figure 142 not displayed.]
@end ifinfo

@c

If the @code{Polygons} lie in parallel planes, there can be no
intersection points.  If they lie in non-parallel, non-coplanar planes,
@code{intersection_points()} first finds the intersection line of the
two planes.  Then it finds the intersection points of this line with the
two @code{Polygons}, if they exist.  There can no more than four
intersection points, in this case.  
@math{v[0]} and @math{v[1]} will be the
intersection points of the line with @code{*this}, while @math{v[2]} and
@math{v[3]} will be the intersection points of the line with @var{r}.  If one
or more of the intersection points doesn't exist, the corresponding
member of @math{v} will contain @code{INVALID_POINT} as a placeholder.  


@example
Point A(1, 1, 1);
Rectangle r(A, 4, 4);
Reg_Polygon p(A, 5, 5);
p.rotate(90, 30);
p.shift(2, 0, 3);
vector <Point> v = r.intersection_points(p);
@end example

@c
@iftex
@tex
\ifmakeexamples
\BEX
\BGRP
\immediate\write\examples{default_focus.set(2, 5, -10, 2, 5, 10, 10);}
\immediate\write\examples{Point A(1, 1, 1);}
\immediate\write\examples{Rectangle r(A, 4, 4);}
\immediate\write\examples{Reg_Polygon p(A, 5, 5);}
\immediate\write\examples{p.rotate(90, 30);}
\immediate\write\examples{p.shift(2, 0, 3);}
\immediate\write\examples{A.mediate(r.get_point(3)).label("$r$", "");}
\immediate\write\examples{p.get_center().mediate(p.get_point(0)).label("$p$", "");}
\immediate\write\examples{r.draw();}
\immediate\write\examples{p.draw();}
\immediate\write\examples{vector <Point> v = r.intersection_points(p);}
\immediate\write\examples{int i = 0;}
\immediate\write\examples{v[0].dotlabel("0", "llft"); }
\immediate\write\examples{v[1].dotlabel("1", "lft"); }
\immediate\write\examples{v[2].dotlabel("2", "llft"); }
\immediate\write\examples{v[3].dotlabel("3", "rt"); }
\immediate\write\examples{v[1].draw(v[2], black, "evenly");}
\immediate\write\examples{v[0].draw(v[3], black, "evenly");}
\immediate\write\examples{v[2].draw(v[0]);}
\OEX{}
\EGRP
\EEX 1
\fi
\PEX
@end tex
@end iftex

@ifhtml
@html
<p align="center">
<br>
<img src="./graphics/png/3DLDFmp.143.png"
alt="[Figure 143. Not displayed.]"
/>
<br>
<br>
Fig. 143.
<br>
</p>
@end html
@end ifhtml

@ifinfo
[Figure 143 not displayed.]
@end ifinfo

@c

In @NEXTFIG{}, the @code{Rectangle} @math{r} and the @code{Reg_Polygon} @math{p}
don't overlap at all, nor does the intersection line of the two planes
intersect with @math{p}.  However, it does intersect with @math{p} at the
labelled @code{Points}.


@example
Point A(1, 1, 1);
Rectangle r(A, 4, 4);
Reg_Polygon p(A, 5, 5);
p.rotate(90, 30);
p.shift(4, 3, 3);
vector <Point> v = r.intersection_points(p);
int i = 0;
for (vector<Point>::iterator iter = v.begin();
 iter != v.end(); ++iter)
 iter->dotlabel(i++, "bot"); 
@end example
  
@c
@iftex
@tex
\ifmakeexamples
\BEX
\BGRP
\immediate\write\examples{default_focus.set(2, 5, -10, 2, 5, 10, 10);}
\immediate\write\examples{Point A(1, 1, 1);}
\immediate\write\examples{Rectangle r(A, 4, 4);}
\immediate\write\examples{Reg_Polygon p(A, 5, 5);}
\immediate\write\examples{p.rotate(90, 30);}
\immediate\write\examples{p.shift(4, 3, 3);}
\immediate\write\examples{r.draw();}
\immediate\write\examples{p.draw();}
\immediate\write\examples{A.label("$r$", "");} 
\immediate\write\examples{p.get_center().label("$p$", "");} 
\immediate\write\examples{vector <Point> v = r.intersection_points(p);}
\immediate\write\examples{v[0].dotlabel("0", "bot"); } 
\immediate\write\examples{v[1].dotlabel("1", "rt"); } 
\immediate\write\examples{v[0].draw(v[1], black, "evenly");}
\OEX{}
\EGRP
\EEX 1
\fi
\PEX  
@end tex
@end iftex

@ifhtml
@html
<p align="center">
<br>
<img src="./graphics/png/3DLDFmp.144.png"
alt="[Figure 144. Not displayed.]"
/>
<br>
<br>
Fig. 144.
<br>
</p>
@end html
@end ifhtml

@ifinfo
[Figure 144 not displayed.]
@end ifinfo

@c


@end deftypefn 

