Roger, once again, you are correct. That should teach me to try to do
something quickly without thinking it through. So, though my solution gets
less and less elegant, I'm reposting a modified version. (I think I have
sufficiently accounted for coincident and collinear points in this version.)
Thanks for your vigilance. Ammar, sorry this took a few iterations, but I
think I've covered the bases this time around.
Brett
function copl=iscoplanar(x,y,z)
% Tests input points for coplanarity.
% COPL = ISCOPLANAR(X,Y,Z) takes input arguments x,y, and z as column
vectors.
% COPL = ISCOPLANAR(x) takes an n x 3 input argument
% in the form [x1 y1 z1;x2 y2 z2;...;xn yn zn]
if nargin == 0
error('Requires at least one input argument.');
elseif nargin == 1
if size(x,2) == 3
% Matrix of all x,y,z is input
allpoints = x;
%Convert input to column vectors
y = x(:,2);
z = x(:,3);
x = x(:,1);
else
error('Invalid input.')
end
else
% Compile a matrix of all x,y,z
allpoints = [x y z];
end
if length(x)<=3
disp('Three or fewer points are necessarily coplanar.');
copl=1;
return;
end
% Select first two vectors that span the test plane
% Any two noncoincident points define v1:
[B,I,J] = unique(allpoints,'rows');
if length(I) == 1
disp('All points are coincident (and hence coplanar).');
copl = 1;
return;
else
v1 = [x(I(2))  x(I(1)), y(I(2))  y(I(1)), z(I(2))  z(I(1))];
end
% If possible, define v2 such that it is not parallel to v1
for i = 1:length(x)
v2 = [x(i)  x(I(1)), y(i)  y(I(1)),z(i)  z(I(1))];
crossprod=cross(v1,v2);
if norm(crossprod) ~= 0
% v1 and v2 are nonparallel, and thus are sufficient to define a
plane
break;
end
end
if crossprod == 0
disp('All points are collinear (and hence coplanar).');
copl = 1;
return;
end
% At this point, v1 and v2 necessarily span a test plane
crossprod=cross(v1,v2);
% %The triple product A.(BxC) vanishes iff vectors A,B, and C are coplanar
for i = 1:length(x)
v3 = [x(i)  x(I(2)), y(i)  y(I(2)), z(i)  z(I(2))];
if dot(crossprod,v3) ~= 0
copl = 0;
return
end
end
copl = 1;
> Brett, on considering the matter more carefully, I believe there is
> another aspect of your method that could cause trouble in certain cases.
> If the user were unlucky and constructed the initial two vectors v1 and v2
> from three points which happened to be colinear, the resulting cross
> product vector would be of zero length and no further points could
> possibly fail the test of being coplanar with the first three. If the
> first three points were nearly colinear and if you put some tolerance
> allowance in your criterion to allow for roundoff errors, then too wide a
> variety of points might pass. I think your initial three points should be
> selected with some considerable degree of care to make this work properly.
>
> Roger
> 
> (Remove "xyzzy" and ".invalid" to send me email.)
> Roger Stafford
