Determine if the direction of the line is clockwise or counterclockwise

I have a list of 2D points (x1, y1), (x2, y2) ...... (Xn, Yn) representing a curved segment, is there any formula to determine if the drawing direction of this segment will be along clockwise or counterclockwise?

any help is appreciated

+3


source to share


3 answers


One of the possible approaches. It should work well enough if the sampling of the line represented by your list of points is uniform and smooth enough, and if the line is simple enough.

  • Subtract the average for the "center" of the line.
  • Convert to polar coordinates to get an angle.
  • Expand the corner to make sure it matters.
  • Check if the overall increment is probable or negative.

I am assuming you have data in vectors x

and y

.



theta = cart2pol(x-mean(x), y-mean(y)); %// steps 1 and 2
theta = unwrap(theta); %// step 3
clockwise = theta(end)<theta(1); %// step 4. Gives 1 if CW, 0 if ACW

      

This only takes into account the integrated effect of all points. It doesn't tell you if there are "kinks" or sections with different turning directions.

A possible improvement would be to replace the mean value x

and y

at some integral. The reason is that if the sample is denser in the area, then the mean will be biased towards that, while the integral will not.

+4


source


Alternatively, you can use some linear algebra. If there are three points a, b and c in this order, do the following:

 1)  create the vectors u = (b-a) = (b.x-a.x,b.y-a.y) and v = (c-b) ...
 2) calculate the cross product uxv = u.x*v.y-u.y*v.x
 3) if uxv is -ve then a-b-c is curving in clockwise direction (and vice-versa).

      



by following a longer curve in the same way, you may even find that the 's' -shaped curve changes from clockwise to counterclockwise, if useful.

+6


source


This is now my approach, as mentioned in the comment to the question -

Another approach: draw a line from the start point to the end point. This line is indeed a vector. The CW has most of its RHS portion of this line. For CCW on the left.

I wrote a sample code to develop this idea. Most of the explanation can be found in the comments in the code.

clear;clc;close all

%% draw a spiral curve
N = 30;
theta = linspace(0,pi/2,N); % a CCW curve
rho = linspace(1,.5,N);
[x,y] = pol2cart(theta,rho);
clearvars theta rho N

plot(x,y);
hold on

%% find "the vector"
vec(:,:,1) = [x(1), y(1); x(end), y(end)]; % "the vector"

scatter(x(1),y(1), 200,'s','r','fill') % square is the starting point
scatter(x(end),y(end), 200,'^','r','fill') % triangle is the ending point
line(vec(:,1,1), vec(:,2,1), 'LineStyle', '-', 'Color', 'r')

%% find center of mass
com = [mean(x), mean(y)]; % center of mass

vec(:,:,2) = [x(1), y(1); com]; % secondary vector (start -> com)

scatter(com(1), com(2), 200,'d','k','fill') % diamond is the com
line(vec(:,1,2), vec(:,2,2), 'LineStyle', '-', 'Color', 'k')

%% find rotation angle
dif = diff(vec,1,1);
[ang, ~] = cart2pol(reshape(dif(1,1,:),1,[]), reshape(dif(1,2,:),1,[]));
clearvars dif

% now you can tell the answer by the rotation angle
if ( diff(ang)>0 )
    disp('CW!')
else
    disp('CCW!')
end

      

On which side of a directed line (vector) you can always point a point by comparing two vectors, namely rotating the vector [start point -> center of mass] with the vector [start point -> end point] and then comparing the rotation angle by 0. Several seconds of animation thinking can help you understand.

+2


source







All Articles