public static int pointCrossingsForPath(PathIterator pi,double px,double py){
  if (pi.isDone()) {
    return 0;
  }
  double coords[]=new double[6];
  if (pi.currentSegment(coords) != PathIterator.SEG_MOVETO) {
    throw new IllegalPathStateException("missing initial moveto " + "in path definition");
  }
  pi.next();
  double movx=coords[0];
  double movy=coords[1];
  double curx=movx;
  double cury=movy;
  double endx, endy;
  int crossings=0;
  while (!pi.isDone()) {
switch (pi.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
      if (cury != movy) {
        crossings+=pointCrossingsForLine(px,py,curx,cury,movx,movy);
      }
    movx=curx=coords[0];
  movy=cury=coords[1];
break;
case PathIterator.SEG_LINETO:
endx=coords[0];
endy=coords[1];
crossings+=pointCrossingsForLine(px,py,curx,cury,endx,endy);
curx=endx;
cury=endy;
break;
case PathIterator.SEG_QUADTO:
endx=coords[2];
endy=coords[3];
crossings+=pointCrossingsForQuad(px,py,curx,cury,coords[0],coords[1],endx,endy,0);
curx=endx;
cury=endy;
break;
case PathIterator.SEG_CUBICTO:
endx=coords[4];
endy=coords[5];
crossings+=pointCrossingsForCubic(px,py,curx,cury,coords[0],coords[1],coords[2],coords[3],endx,endy,0);
curx=endx;
cury=endy;
break;
case PathIterator.SEG_CLOSE:
if (cury != movy) {
crossings+=pointCrossingsForLine(px,py,curx,cury,movx,movy);
}
curx=movx;
cury=movy;
break;
}
pi.next();
}
if (cury != movy) {
crossings+=pointCrossingsForLine(px,py,curx,cury,movx,movy);
}
return crossings;
}

public static int pointCrossingsForPath ( PathIterator pi , double px , double py ) { if ( pi . isDone ( ) ) { return 0 ; } double coords [ ] = new double [ 6 ] ; if ( pi . currentSegment ( coords ) != PathIterator . SEG_MOVETO ) { throw new IllegalPathStateException ( "missing initial moveto " + "in path definition" ) ; } pi . next ( ) ; double movx = coords [ 0 ] ; double movy = coords [ 1 ] ; double curx = movx ; double cury = movy ; double endx , endy ; int crossings = 0 ; while ( ! pi . isDone ( ) ) { switch ( pi . currentSegment ( coords ) ) { case PathIterator . SEG_MOVETO : if ( cury != movy ) { crossings += pointCrossingsForLine ( px , py , curx , cury , movx , movy ) ; } movx = curx = coords [ 0 ] ; movy = cury = coords [ 1 ] ; break ; case PathIterator . SEG_LINETO : endx = coords [ 0 ] ; endy = coords [ 1 ] ; crossings += pointCrossingsForLine ( px , py , curx , cury , endx , endy ) ; curx = endx ; cury = endy ; break ; case PathIterator . SEG_QUADTO : endx = coords [ 2 ] ; endy = coords [ 3 ] ; crossings += pointCrossingsForQuad ( px , py , curx , cury , coords [ 0 ] , coords [ 1 ] , endx , endy , 0 ) ; curx = endx ; cury = endy ; break ; case PathIterator . SEG_CUBICTO : endx = coords [ 4 ] ; endy = coords [ 5 ] ; crossings += pointCrossingsForCubic ( px , py , curx , cury , coords [ 0 ] , coords [ 1 ] , coords [ 2 ] , coords [ 3 ] , endx , endy , 0 ) ; curx = endx ; cury = endy ; break ; case PathIterator . SEG_CLOSE : if ( cury != movy ) { crossings += pointCrossingsForLine ( px , py , curx , cury , movx , movy ) ; } curx = movx ; cury = movy ; break ; } pi . next ( ) ; } if ( cury != movy ) { crossings += pointCrossingsForLine ( px , py , curx , cury , movx , movy ) ; } return crossings ; }
calculates the number of times the given path crosses the ray extending to the right from ( px , py ) . if the point lies on a part of the path , then no crossings are counted for that intersection . + 1 is added for each crossing where the y coordinate is increasing - 1 is added for each crossing where the y coordinate is decreasing the return value is the sum of all crossings for every segment in the path . the path must start with a seg_moveto , otherwise an exception is thrown . the caller must check p [ xy ] for nan values . the caller may also reject infinite p [ xy ] values as well .
