The Weiler-Atherton algorithm is capable of clipping a concave polygon with interior holes to the boundaries of another concave polygon, also with interior holes. The polygon to be clipped is called the subject polygon (SP) and the clipping region is called the clip polygon (CP). The new boundaries created by clipping the SP against the CP are identical to portions of the CP. No new edges are created. Hence, the number of resulting polygons is minimized.

The algorithm describes both the SP and the CP by a circular list of vertices. The exterior boundaries of the polygons are described clockwise, and the interior boundaries or holes are described counter-clockwise. When traversing the vertex list, this convention ensures that the inside of the polygon is always to the right. The boundaries of the SP and the CP may or may not intersect. If they intersect, the intersections occur in pairs. One of the intersections occurs when the SP edge enters the inside of the CP and one when it leaves. Fundamentally, the algorithm starts at an entering intersection and follows the exterior boundary of the SP clockwise until an intersection with a CP is found. At the intersection a right turn is made, and the exterior of the CP is followed clockwise until an intersection with the SP is found. Again, at the intersection, a right turn is made, with the SP now being followed. The process is continued until the starting point is reached. Interior boundaries of the SP are followed counter-clockwise.

#include <graphics.h>  
class point  
{  
 public:  
  int x, y, sense;  
 point * link;  
 point()  
 {  
  link = NULL;  
  sense = 0;  
 }  
};  
point * p, * v = NULL;  
const int n = 9;  
void main()  
{  
 int gd = DETECT, gm;  
 initgraph( & gd, & gm, "");  
 point * ptr, * vptr;  
 for (int i = 0; i < n; i++)  
 {  
  point * t;  
  t = new point;  
  cout << i << " ";  
  cin >> t -> x >> t -> y;  
  if (p == NULL)  
  {  
   ptr = t;  
   p = ptr;  
  } else  
  {  
   ptr -> link = t;  
   ptr = t;  
  }  
 }  
 ptr -> link = p;  
 v = new point;  
 v -> x = 0;  
 v -> y = -getmaxy() / 2;  
 ptr = new point;  
 v -> link = ptr;  
 ptr -> x = 0;  
 ptr -> y = getmaxy() / 2;  
 ptr -> link = v;  
 ptr = p;  
 for (i = 0; i < n; i++)  
 {  
  if (ptr -> x < 0 && ptr -> link -> x > 0)  
  {  
   point * p1, * v1;  
   p1 = new point;  
   p1 -> sense = 1;  
   v1 = new point;  
   p1 -> x = 0;  
   float m = (ptr -> y - ptr -> link -> y) / (ptr -> x - ptr -> link -> x);  
   p1 -> y = ptr -> y + (0 - ptr -> x) * m;  
   * v1 = * p1;  
   point * temp;  
   temp = ptr -> link;  
   ptr -> link = p1;  
   p1 -> link = temp;  
   vptr = v;  
   while (vptr -> link -> y < v1 -> y)  
    vptr = vptr -> link;  
   temp = vptr -> link;  
   vptr -> link = v1;  
   v1 -> link = temp;  
   ptr = ptr -> link;  
  }  
  if (ptr -> x > 0 && ptr -> link -> x < 0)  
  {  
   point * p1, * v1;  
   p1 = new point;  
   p1 -> sense = -1;  
   v1 = new point;  
   p1 -> x = 0;  
   float m = (ptr -> y - ptr -> link -> y) / (ptr -> x - ptr -> link -> x);  
   p1 -> y = ptr -> y + (0 - ptr -> x) * m;  
   * v1 = * p1;  
   point * temp;  
   temp = ptr -> link;  
   ptr -> link = p1;  
   p1 -> link = temp;  
   vptr = v;  
   while (vptr -> link -> y < v1 -> y)  
    vptr = vptr -> link;  
   temp = vptr -> link;  
   vptr -> link = v1;  
   v1 -> link = temp;  
   ptr = ptr -> link;  
  }  
  ptr = ptr -> link;  
 }  
 ptr = p;  
 vptr = v;  
 while (ptr -> sense != 1)  
  ptr = ptr -> link;  
 point * start = ptr;  
 int d = 0;  
 while (d == 0 || start != ptr)  
 {  
  d = 1;  
  do  
  {  
   line(getmaxx() / 2 + ptr -> x, getmaxy() / 2 - ptr -> y, getmaxx() / 2 + ptr -> link -> x, getmaxy() / 2 - ptr -> link -> y);  
   ptr = ptr -> link;  
  } while (ptr -> sense == 0);  
  point * q;  
  vptr = v;  
  while (vptr)  
  {  
   if (vptr -> x == ptr -> x && vptr -> y == ptr -> y)  
   {  
    q = vptr;  
    break;  
   }  
   vptr = vptr -> link;  
  }  
  ptr = ptr -> link;  
  do  
  {  
   line(getmaxx() / 2 + q -> x, getmaxy() / 2 - q -> y, getmaxx() / 2 + q -> link -> x, getmaxy() / 2 - q -> link -> y);  
   q = q -> link;  
  } while (q -> sense == 0);  
  while (ptr -> sense == 0)  
   ptr = ptr -> link;  
 }  
}