scribble/src/ink_intersect.c File Reference

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include <limits.h>
#include "ink_intersect.h"
#include "ScribbleLog.h"

Go to the source code of this file.

Defines

#define min(a, b)   (((a)<(b))?(a):(b))
#define max(a, b)   (((a)>(b))?(a):(b))
#define TOLERANCE_PIXELS   -3
#define LONELY_STROKE_POINTS   4
#define ERASER_SIZE   8

Functions

int isPointOutOfRange (int x, int y, int x1, int y1, int x2, int y2)
int isPointOutOfStroke (PtrStroke pStroke, GdkPoint *p)
gboolean isLineCrossStrokeRange (PtrStroke pStroke, GdkPoint *p0, GdkPoint *p1, int *p_rec_width, int *p_rect_height)
int lineIntersects (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
int isIntersects (PtrStroke pStroke, GdkPoint *srcPt1, GdkPoint *srcPt2)
int hitTest (PtrStroke pStroke, GdkPoint *point)
PtrStrokeIntersections_t findIntersections (PtrStroke pStroke, GdkPoint *srcPt1, GdkPoint *srcPt2)
void delStroke (PtrInk pink, PtrStroke pPrev, PtrStroke *ppCur, PtrInk pDelInk)
void delStrokesByLine (PtrInk pink, GdkPoint *p0, GdkPoint *p1, PtrInk pDelInk)
void delInterSectLines (PtrInk pink, GdkPoint *p0, GdkPoint *p1)


Define Documentation

#define ERASER_SIZE   8

Definition at line 196 of file ink_intersect.c.

#define LONELY_STROKE_POINTS   4

Definition at line 52 of file ink_intersect.c.

#define max ( a,
 )     (((a)>(b))?(a):(b))

Definition at line 46 of file ink_intersect.c.

#define min ( a,
 )     (((a)<(b))?(a):(b))

Copyright (C) 2005-2008 iRex Technologies B.V. All rights reserved.

Definition at line 45 of file ink_intersect.c.

#define TOLERANCE_PIXELS   -3

Definition at line 51 of file ink_intersect.c.


Function Documentation

void delInterSectLines ( PtrInk  pink,
GdkPoint *  p0,
GdkPoint *  p1 
)

Definition at line 385 of file ink_intersect.c.

00386 {
00387     PtrStrokeIntersections_t intersections;
00388     int i,j;
00389     StrokeIntersection_t  *pCurIntersection=NULL;
00390 
00391     PtrStroke pCurStroke = pink->firstStroke;
00392     int nStrokes=pink->nStrokes;//it may change when running
00393     for (i=0; i<nStrokes ;i++,pCurStroke = pCurStroke->nextStroke)
00394     {
00395         if ( NULL==pCurStroke ) break;
00396 
00397         intersections = findIntersections(pCurStroke,p0,p1);
00398 
00399         if ( NULL==intersections ) continue;
00400 
00401         pCurIntersection = intersections->interSection;
00402 
00403         for (j=0; j<intersections->nSections;i++)
00404         {
00405             if ( NULL==pCurIntersection ) break;
00406         //Erase the intersection,and if possible,split it
00407 /*
00408             ink_draw_line(pCurIntersection->beginPt->x,
00409             pCurIntersection->beginPt->y,
00410             pCurIntersection->endPt->x,
00411             pCurIntersection->endPt->y);
00412 */
00413         
00414             pCurIntersection = pCurIntersection->pNextSection;
00415         }
00416     }//end for stroke iteration
00417 }

Here is the call graph for this function:

void delStroke ( PtrInk  pink,
PtrStroke  pPrev,
PtrStroke ppCur,
PtrInk  pDelInk 
)

Definition at line 284 of file ink_intersect.c.

00285 {
00286     if( NULL==pink || NULL==*ppCur) return ;
00287     //validate accurracy
00288     if( pPrev!=NULL && pPrev->nextStroke!=*ppCur) return ;
00289 
00290     PtrStroke pNext=(*ppCur)->nextStroke;
00291     //remove the Strok to deleted ink
00292     if( NULL==pDelInk->firstStroke)
00293     {
00294         pDelInk->firstStroke=pDelInk->lastStroke=*ppCur;
00295     }
00296     else
00297     {
00298         pDelInk->lastStroke->nextStroke=*ppCur;
00299         pDelInk->lastStroke=*ppCur;
00300     }
00301     pDelInk->nStrokes++;
00302     (*ppCur)->nextStroke=NULL;
00303 
00304     pink->nStrokes--;
00305     *ppCur=pNext;
00306     if( NULL==pPrev )
00307     {//head pointer
00308         pink->firstStroke=pNext;
00309     }
00310     else
00311     {
00312         pPrev->nextStroke=pNext;
00313     }
00314     if( NULL==pNext)
00315     {//tail pointer
00316         pink->lastStroke=pPrev;
00317     }
00318     SB_INKPRINTF("removed!\n");
00319 }

void delStrokesByLine ( PtrInk  pink,
GdkPoint *  p0,
GdkPoint *  p1,
PtrInk  pDelInk 
)

Definition at line 323 of file ink_intersect.c.

00324 {
00325     int i;
00326 
00327     if( NULL==pink || NULL==pDelInk) return;
00328 
00329     PtrStroke pCurStroke = pink->firstStroke;
00330     PtrStroke pPrevStroke = NULL;
00331     
00332     gboolean bRealIntersect,bCrossStrokeRange;
00333     int rect_w,rect_h;
00334             
00335     int nStrokes=pink->nStrokes;//it may change when running
00336     for (i=0; i< nStrokes ;i++)
00337     {
00338         if ( NULL==pCurStroke ) break;
00339         //a little inaccuracy,but accelerate more,
00340         //if( isPointOutOfStroke(pCurStroke,p0) &&  /
00341         //    isPointOutOfStroke(pCurStroke,p1) )
00342         bCrossStrokeRange=isLineCrossStrokeRange(pCurStroke,p0,p1,&rect_w,&rect_h);
00343         bRealIntersect=FALSE;
00344         if( pCurStroke->nPoints <= LONELY_STROKE_POINTS )
00345         {
00346             if( rect_w>=TOLERANCE_PIXELS && rect_h>=TOLERANCE_PIXELS )
00347             {   
00348                 SB_INKPRINTF("\n__special:p0=[%d,%d],p1=[%d,%d],[rect_w=%d,rect_h=%d]\n",
00349                               p0->x,p0->y,p1->x,p1->y,rect_w,rect_h);
00350                 
00351                 //for LONELEY point ,do hittest
00352                 if( hitTest(pCurStroke, p0) || hitTest(pCurStroke, p1))
00353                 { 
00354                     bRealIntersect=TRUE;
00355                 }
00356                 SB_INKPRINTF("hitTest: bRealIntersect=%d\n",bRealIntersect);
00357             }
00358         }
00359         if( !bRealIntersect && bCrossStrokeRange)
00360         {
00361             if( isIntersects(pCurStroke,p0,p1) )
00362             {
00363                 bRealIntersect=TRUE;
00364             }
00365             SB_INKPRINTF("isIntersects: bRealIntersect=%d\n",bRealIntersect);
00366         }
00367         if(bRealIntersect)
00368         {
00369             SB_INKPRINTF("\n(%d,%d),(%d,%d)intersect,range[(%d,%d),(%d,%d)]\n",
00370                          p0->x,p0->y,p1->x,p1->y,
00371                          pCurStroke->min_x,pCurStroke->min_y,
00372                          pCurStroke->max_x,pCurStroke->max_y );
00373             //remove current stroke,current move to next
00374             delStroke(pink,pPrevStroke,&pCurStroke,pDelInk);
00375             continue;//need not change prev,and current is changed.
00376         }
00377         //not intersect and not in range.
00378         pPrevStroke=pCurStroke;
00379         pCurStroke = pCurStroke->nextStroke;
00380     }//end for stroke iteration
00381 }

Here is the call graph for this function:

PtrStrokeIntersections_t findIntersections ( PtrStroke  pStroke,
GdkPoint *  srcPt1,
GdkPoint *  srcPt2 
)

Definition at line 220 of file ink_intersect.c.

00221 {
00222     InkPoint *targetPt1, *targetPt2;
00223     int    i;
00224     PtrStrokeIntersections_t intersections = NULL;
00225     StrokeIntersection_t  *pSection;
00226     StrokeIntersection_t  *pCurSection = NULL;;
00227 
00228     if ( (srcPt1->x == srcPt2->x) && (srcPt1->y == srcPt2->y) )
00229     {
00230         return NULL;
00231     }
00232 
00233     //allocate memory 
00234     intersections = (PtrStrokeIntersections_t)
00235             malloc(sizeof(StrokeIntersections_t));
00236     //assert(intersections != NULL);
00237     memset(intersections, 0, sizeof(StrokeIntersections_t)); 
00238 
00239     targetPt1 = pStroke->firstPoint;
00240     for (i=1; i < pStroke->nPoints; i++)
00241     {
00242         targetPt2 = targetPt1->nextPoint;
00243         if (  (targetPt1->x != targetPt2->x)
00244                ||(targetPt1->y != targetPt2->y) )
00245         {
00246             if (lineIntersects(srcPt1->x - pStroke->iPenSize/2,
00247                 srcPt1->y - pStroke->iPenSize/2,
00248                 srcPt2->x + pStroke->iPenSize/2,
00249                 srcPt2->y + pStroke->iPenSize/2,
00250                 targetPt1->x,
00251                 targetPt1->y,
00252                 targetPt2->x,
00253                 targetPt2->y) > 0)
00254             {
00255                 pSection = (StrokeIntersection_t  *)
00256                         malloc(sizeof(StrokeIntersection_t));
00257                 //assert(pSection != NULL);
00258                 pSection->beginPt = targetPt1;
00259                 pSection->endPt = targetPt2;
00260                 pSection->pNextSection = NULL;
00261                 //add the section into the section list
00262                 if (intersections->interSection == NULL)
00263                 {
00264                     pCurSection = intersections->interSection = pSection;
00265                 }
00266                 else if (pCurSection != NULL)
00267                 {
00268                     pCurSection->pNextSection = pSection;
00269                 }
00270                 else
00271                 {
00272                     SB_INKERRPRINTF("ERROR in Scribble\n");
00273                 }
00274                 intersections->nSections++;
00275             }
00276         }
00277         //update point ptr
00278         targetPt1 = targetPt2;
00279     }
00280     return intersections;
00281 }

Here is the call graph for this function:

int hitTest ( PtrStroke  pStroke,
GdkPoint *  point 
)

Definition at line 197 of file ink_intersect.c.

00198 {
00199     PtrInkPoint pt;
00200     int i;
00201 
00202     pt = pStroke->firstPoint;
00203     //int iEraserSize=pStroke->iPenSize;
00204     int iEraserSize=ERASER_SIZE;
00205     for (i=0; i < pStroke->nPoints; i++)
00206     { 
00207         if ( ( pt->x >= (point->x - iEraserSize/2))
00208                && ( pt->x <= (point->x + iEraserSize/2))
00209                && ( pt->y >= (point->y - iEraserSize/2))
00210                && ( pt->y <= (point->y + iEraserSize/2)) )
00211         {
00212             return 1;
00213         }
00214         pt = pt->nextPoint;
00215     }
00216     return 0;
00217 }

int isIntersects ( PtrStroke  pStroke,
GdkPoint *  srcPt1,
GdkPoint *  srcPt2 
)

Definition at line 158 of file ink_intersect.c.

00159 {
00160     InkPoint *targetPt1, *targetPt2;
00161     int i;
00162 
00163     if ((srcPt1->x == srcPt2->x) && (srcPt1->y == srcPt2->y))
00164     {
00165         return 0;//??
00166     }
00167 
00168     targetPt1 = pStroke->firstPoint;
00169 
00170     for (i=1; i < pStroke->nPoints; i++)
00171     {
00172         targetPt2 = targetPt1->nextPoint;
00173         if (  (targetPt1->x != targetPt2->x)
00174             ||(targetPt1->y != targetPt2->y) )
00175         {
00176             if (lineIntersects(srcPt1->x - pStroke->iPenSize/2, 
00177                 srcPt1->y - pStroke->iPenSize/2, 
00178                 srcPt2->x + pStroke->iPenSize/2, 
00179                 srcPt2->y + pStroke->iPenSize/2, 
00180                 targetPt1->x, 
00181                 targetPt1->y, 
00182                 targetPt2->x, 
00183                 targetPt2->y) > 0)
00184             {
00185                 return 1;
00186                 break;
00187             }
00188         }
00189         //update point ptr
00190         targetPt1 = targetPt2;
00191     }
00192     return 0;
00193 }

Here is the call graph for this function:

gboolean isLineCrossStrokeRange ( PtrStroke  pStroke,
GdkPoint *  p0,
GdkPoint *  p1,
int *  p_rec_width,
int *  p_rect_height 
)

Definition at line 70 of file ink_intersect.c.

00072 {    
00073     if( NULL==p_rec_width || NULL==p_rect_height) return FALSE;
00074     
00075     int dest_x,dest_y;
00076     dest_x = max (min(p0->x,p1->x), pStroke->min_x);
00077     dest_y = max (min(p0->y,p1->y), pStroke->min_y);
00078     *p_rec_width = min (max(p0->x,p1->x), pStroke->max_x)- dest_x;
00079     *p_rect_height = min (max(p0->y,p1->y), pStroke->max_y) - dest_y;
00080     
00081     return ( *p_rec_width>=0 && *p_rect_height>=0);
00082 }

int isPointOutOfRange ( int  x,
int  y,
int  x1,
int  y1,
int  x2,
int  y2 
)

Definition at line 56 of file ink_intersect.c.

00057 {
00058     return ( x < x1 || x>x2 || y<y1 || y>y2);
00059 } 

int isPointOutOfStroke ( PtrStroke  pStroke,
GdkPoint *  p 
)

Definition at line 61 of file ink_intersect.c.

00062 {
00063     return isPointOutOfRange(p->x,p->y,
00064                              pStroke->min_x,pStroke->min_y,
00065                              pStroke->max_x,pStroke->max_y );
00066 }

Here is the call graph for this function:

int lineIntersects ( int  x1,
int  y1,
int  x2,
int  y2,
int  x3,
int  y3,
int  x4,
int  y4 
)

Definition at line 86 of file ink_intersect.c.

00088 { 
00089     long ry1, ry2, ry3, ry4; 
00090     long rx1, rx2, rx4;
00091 
00092     if ( (min(x1,x2) > max(x3,x4)) || (min(x3,x4) > max(x1,x2)) )
00093     {
00094         return 0;
00095     }
00096 
00097     if ( (min(y1,y2) > max(y3,y4)) || (min(y3,y4) > max(y1,y2)) )
00098     {
00099         return 0;
00100     }
00101 
00102     x2 -= x1;  y2 -= y1; 
00103     x3 -= x1;  y3 -= y1; 
00104     x4 -= x1;  y4 -= y1; 
00105 
00106     ry3 = (long) y3 * x2 - (long) x3 * y2; 
00107     ry4 = (long) y4 * x2 - (long) x4 * y2; 
00108 
00109     if((ry3 > 0 && ry4 > 0) || (ry3 < 0 && ry4 < 0)) 
00110         return (0); 
00111 
00112     x1 = -x3;  y1 = -y3; 
00113     x2 -= x3;  y2 -= y3; 
00114     x4 -= x3;  y4 -= y3; 
00115 
00116     ry1 = (long) y1 * x4 - (long) x1 * y4; 
00117     ry2 = (long) y2 * x4 - (long) x2 * y4; 
00118 
00119     if((ry1 > 0 && ry2 > 0) || (ry1 < 0 && ry2 < 0)) 
00120         return 0; 
00121 
00122     if(ry1 || ry2 || ry3 || ry4) 
00123         return 1; 
00124 
00125     /* special cases: */ 
00126     if(x4 == 0 && y4 == 0)
00127     { 
00128         if((x1 > 0 && x2 > 0) || (x1 < 0 && x2 < 0)) return 0; 
00129         if(x1 == 0 && x2 == 0)
00130         { 
00131             if ((y1 > 0 && y2) > 0 || (y1 < 0 && y2 < 0)) return 0; 
00132         } 
00133         return 1; 
00134     } 
00135 
00136     rx1 = (long) x1 * x4 + (long) y1 * y4; 
00137     rx2 = (long) x2 * x4 + (long) y2 * y4; 
00138     rx4 = (long) x4 * x4 + (long) y4 * y4; 
00139 
00140     if(rx1 >= 0 && rx1 <= rx4) return 1; 
00141 
00142     if(rx2 >= 0 && rx2 <= rx4) return 1; 
00143 
00144     if(rx1 <= rx2)
00145     { 
00146         if(0 >= rx1 && 0 <= rx2) return 1; 
00147         if(rx4 >= rx1 && rx4 <= rx2) return 1; 
00148     } 
00149     else
00150     { 
00151         if(0 >= rx2 && 0 <= rx1) return 1; 
00152         if(rx4 >= rx2 && rx4 <= rx1) return 1; 
00153     } 
00154     return 0; 
00155 } 


Generated on Sun Dec 14 17:14:36 2008 by  doxygen 1.5.6