classdef ConvexPoly < handle
% Operations on convex polygons

properties
% A convex polygon has n vertices that are points.
% The bounding circle is a circle that encloses the polygon.
v = Point.empty(); % A vector of polygon vertices.
n % The number of vertices.
C = Circle.empty(); % The bounding circle
end % properties

methods
function P = ConvexPoly(n)
% Construct a random convex polygon with n sides
m = n^2; u = -1+2*rand(m,1); v = -1+2*rand(m,1);
idx = convhull(u,v);
x = u(idx(1:n));
y = v(idx(1:n));
% Create the convex polygon object...
P.n = n;
for k=1:n
P.v(k) = Point(x(k),y(k));
end
% The bounding circle...
xc = mean(x);
yc = mean(x);
r = max(sqrt((x-xc).^2+(y-yc).^2));
P.C = Circle(r,Point(xc,yc));
end

function Translate(ThisConvexPoly,delX,delY)
% delX and delY are real numbers.
% For every vertex in ThisConvexPoly, delX is added to the
% x-coordinate and delY is added to the y-coordinate.
P = ThisConvexPoly;
for k=1:P.n
P.v(k).Translate(delX,delY);
end
P.C.Translate(delX,delY);
end

function Show(ThisConvexPoly,c)
% Plots ThisConvexPoly
% The color is specified by the character c.
% Assumes hold is on.
n = ThisConvexPoly.n;
x = zeros(1,n);
y = zeros(1,n);
for k=1:n
x(k) = ThisConvexPoly.v(k).x;
y(k) = ThisConvexPoly.v(k).y;
end
plot([x x(1)],[y y(1)],c)
end

function alfa = DiffSide(ThisConvexPoly,R,P1,P2)
% R, P1, and P2 are distinct points.
% Let L be the line through P1 and P2.
% alfa is true if and only if no vertex in ThisConvexPoly is
% on the same side of L as R.
Q = ThisConvexPoly;
alfa = 1;
k=1;
while k<=Q.n && alfa
alfa = R.DiffSide(Q.v(k),P1,P2);
k=k+1;
end
end

function alfa = Isolated(ThisConvexPoly,ThatConvexPoly)
% alfa is true if and only if ThisConvexPoly looks to be
% be disjoint from ThatConvexPoly when we look at the latter's
% sidelines.
A = ThisConvexPoly;
B = ThatConvexPoly;
k=1;
alfa = 0;
while k<=B.n && ~alfa
% Consider the sideline through B.v(k) and its successor.
% Check to see if A is on the opposite side of B.v(k)'s
% predecessor.
if k<=B.n-2
alfa = A.DiffSide(B.v(k+2),B.v(k),B.v(k+1));
elseif k==B.n-1
alfa = A.DiffSide(B.v(1),B.v(k),B.v(k+1));
else
alfa = A.DiffSide(B.v(2),B.v(k),B.v(1));
end
k=k+1;
end
end

function alfa = Disjoint(ThisConvexPoly,ThatConvexPoly)
% alfa is true if and only if ThisConvexPoly is disjoint from
% ThatConvexPoly
P = ThisConvexPoly;
Q = ThatConvexPoly;
beta = P.C.center.Dist(Q.C.center)>P.C.r+Q.C.r;
alfa = beta || P.Isolated(Q) || Q.Isolated(P);
% Note that because of lazy evaluation, the processing the "||"
% terminates as soon as it is discovered that the two polygons are
% isolated.
end
end % methods
end % classdef