00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <malloc.h>
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include "ToySegment.h"
00016 #include "ToySegmentList.h"
00017
00018
00019 void TMM_RemoveFromList(SegList *node)
00020 {
00021
00022 if(node==NULL) return;
00023
00024
00025 if(node->prev!=NULL) node->prev->next=node->next;
00026 if(node->next!=NULL) node->next->prev=node->prev;
00027
00028
00029 node->prev=node->next=NULL;
00030 }
00031
00033 void TMM_InsertBefore(SegList *pos, SegList *node)
00034 {
00035 node->next=pos;
00036
00037 if(pos!=NULL)
00038 {
00039 node->prev=pos->prev;
00040 if(pos->prev!=NULL) pos->prev->next=node;
00041 pos->prev=node;
00042 }
00043 }
00044
00046 void TMM_InsertAfter(SegList *pos, SegList *node)
00047 {
00048
00049 node->prev=pos;
00050 if(pos==NULL) node->next=NULL;
00051 else node->next=pos->next;
00052
00053 if(pos!=NULL)
00054 {
00055 if(pos->next!=NULL)
00056 {
00057 pos->next->prev=node;
00058 }
00059 pos->next=node;
00060 }
00061 }
00062
00066 SegList *TMM_OrderedInsert(SegList *list, SegList *node)
00067 {
00068
00069 if(list==NULL)
00070 {
00071 node->next=node->prev=NULL;
00072 return(node);
00073 }
00074
00075
00076 while(list!=NULL)
00077 {
00078 if(list->seg.pos>node->seg.pos)
00079 {
00080 TMM_InsertBefore(list,node);
00081 return(TMM_SeekSegListHead(list));
00082 }
00083 else if(list->next==NULL)
00084 {
00085 TMM_InsertAfter(list,node);
00086 return(TMM_SeekSegListHead(list));
00087 }
00088
00089 list=list->next;
00090 }
00091
00092
00093 return(NULL);
00094 }
00095
00096
00097 int TMM_SegListSize(SegList *list)
00098 {
00099 int len=0;
00100
00101
00102
00103 list=TMM_SeekSegListHead(list);
00104
00105 if(list==NULL) return(0);
00106
00107 do
00108 {
00109 len++;
00110 list=list->next;
00111 } while(list!=NULL);
00112
00113 return(len);
00114 }
00115
00116
00117
00118
00119 int TMM_FindSegSpace(SegList *list, int n)
00120 {
00121 list=TMM_SeekSegListHead(list);
00122
00123 while(list!=NULL)
00124 {
00125 if(list->seg.len>=n) return(list->seg.pos);
00126 list=list->next;
00127 }
00128
00129 return(-1);
00130 }
00131
00132 SegList *TMM_CopySegList(SegList *list)
00133 {
00134 SegList *copy=NULL;
00135 list=TMM_SeekSegListHead(list);
00136
00137 while(list!=NULL)
00138 {
00139 SegList *node=TMM_CreateSegList(list->seg.pos,list->seg.len,NULL,NULL);
00140 copy=TMM_AppendSegList(copy,node);
00141 list=list->next;
00142 }
00143 return(copy);
00144 }
00145
00146 SegList *TMM_AddAreaToSegList(SegList *list, int pos, int len)
00147 {
00148
00149 ToySegment seg;
00150 int intersect=0;
00151 SegList *head;
00152
00153 seg.pos=pos;
00154 seg.len=len;
00155
00156 if(list==NULL) return(NULL);
00157
00158 list=TMM_SeekSegListHead(list);
00159 head=list;
00160
00161 while(list!=NULL)
00162 {
00163 intersect|=TMM_AreaIntersectsSeg(&seg,&(list->seg));
00164 list=list->next;
00165 }
00166 list=head;
00167
00168 if(intersect)
00169 {
00170 return(list);
00171 }
00172 else
00173 {
00174 SegList *nlist=TMM_CreateSegList(seg.pos,seg.len,NULL,NULL);
00175 TMM_AppendSegList(head,nlist);
00176 list=TMM_SortSegList(list);
00177 list=TMM_MergeSegList(list);
00178 return(list);
00179 }
00180 }
00181
00182 SegList *TMM_MergeSegList(SegList *list)
00183 {
00184 SegList *head;
00185
00186 if(list==NULL) return(NULL);
00187
00188 list=TMM_SeekSegListHead(list);
00189 head=list;
00190
00191 while(list->next!=NULL)
00192 {
00193
00194
00195 if(list->seg.len+list->seg.pos == list->next->seg.pos)
00196 {
00197 SegList *temp=list->next;
00198
00199 list->seg.len+=temp->seg.len;
00200
00201 if(temp->prev!=NULL) temp->prev->next=temp->next;
00202 if(temp->next!=NULL) temp->next->prev=list;
00203
00204 free(temp);
00205
00206 continue;
00207 }
00208
00209 list=list->next;
00210 }
00211
00212 return(head);
00213 }
00214
00215 int TMM_CompSegList(const SegList *l1, const SegList *l2)
00216 {
00217 if(l1->seg.pos>l2->seg.pos) return(1);
00218 else if(l1->seg.pos<l2->seg.pos) return(-1);
00219 else return(0);
00220 }
00221
00222 SegList *TMM_SortSegList(SegList *list)
00223 {
00224 if(list==NULL) return(NULL);
00225
00226 list=TMM_SeekSegListHead(list);
00227
00228 while(list->next!=NULL)
00229 {
00230
00231 if(TMM_CompSegList(list,list->next)>0)
00232 {
00233
00234 ToySegment seg=list->next->seg;
00235 list->next->seg=list->seg;
00236 list->seg=seg;
00237 if(list->prev!=NULL) list=list->prev;
00238 continue;
00239 }
00240
00241 list=list->next;
00242 }
00243
00244 list=TMM_SeekSegListHead(list);
00245 return(list);
00246 }
00247
00248 SegList *TMM_RemoveAreaFromSegList(SegList *list, int pos, int len)
00249 {
00250
00251 ToySegment seg;
00252 SegList *tail=TMM_SeekSegListEnd(list);
00253 list=TMM_SeekSegListHead(list);
00254
00255 seg.pos=pos;
00256 seg.len=len;
00257
00258 while(list!=NULL)
00259 {
00260 int v;
00261
00262 ToySegment segs[2];
00263
00264 v=TMM_SubtractSegs(&(list->seg),&seg,segs);
00265
00266 switch(v)
00267 {
00268 case -1:
00269 break;
00270
00271 case 0:
00272 {
00273
00274 SegList *tmp=list->next;
00275
00276 if((list->prev==NULL)&&(list->next==NULL))
00277
00278
00279 {
00280 free(list);
00281 return(NULL);
00282 }
00283
00284 if(list->prev!=NULL)
00285 {
00286 list->prev->next = list->next;
00287 }
00288 if(list->next!=NULL)
00289 {
00290 list->next->prev=list->prev;
00291 }
00292
00293
00294 free(list);
00295 list=tmp;
00296 continue;
00297 }
00298
00299 case 1:
00300 list->seg.len=segs[0].len;
00301 list->seg.pos=segs[0].pos;
00302
00303 break;
00304
00305 case 2:
00306 {
00307 SegList *nseg=TMM_CreateSegList(segs[1].pos,segs[1].len,NULL,NULL);
00308
00309 list->seg.len=segs[0].len;
00310 list->seg.pos=segs[0].pos;
00311
00312 TMM_AppendSegList(tail,nseg);
00313 TMM_SeekSegListEnd(tail);
00314 break;
00315 }
00316 }
00317
00318
00319 list=list->next;
00320 }
00321
00322 list=TMM_SeekSegListHead(tail);
00323 list=TMM_SortSegList(list);
00324
00325 return(list);
00326
00327 }
00328
00329 void TMM_PrintSegList(SegList *list)
00330 {
00331 int n=0;
00332 list=TMM_SeekSegListHead(list);
00333 printf("Seg Pos Length\n");
00334 printf("----------------------\n");
00335 while(list!=NULL)
00336 {
00337 printf("%03d %03d %03d\n",n,list->seg.pos,list->seg.len);
00338 list=list->next;
00339 n++;
00340 }
00341 }
00342
00343
00344 SegList *TMM_AppendSegList(SegList *list,SegList *node)
00345 {
00346 list=TMM_SeekSegListEnd(list);
00347
00348 if(node==NULL) return(list);
00349 if(list==NULL)
00350 {
00351 node->prev=NULL;
00352 return node;
00353 }
00354 else
00355 {
00356 node->prev=list;
00357 list->next=node;
00358 return(TMM_SeekSegListHead(list));
00359 }
00360 }
00361
00362 SegList *TMM_CreateSegList(int pos, int len, SegList *prev, SegList *next)
00363 {
00364 SegList *list=(SegList *)malloc(sizeof(SegList));
00365
00366 if(list==NULL)
00367 {
00368
00369 return(NULL);
00370 }
00371 else
00372 {
00373 list->next=next;
00374 list->prev=prev;
00375 list->seg.len=len;
00376 list->seg.pos=pos;
00377 return(list);
00378 }
00379 }
00380
00381 SegList *TMM_SeekSegListHead(SegList *list)
00382 {
00383 SegList *l=list;
00384
00385 if(l==NULL) return NULL;
00386
00387 while(l->prev!=NULL) l=l->prev;
00388 return(l);
00389 }
00390
00391
00392 SegList *TMM_SeekSegListEnd(SegList *list)
00393 {
00394 SegList *l=list;
00395
00396 if(l==NULL) return NULL;
00397
00398 while(l->next!=NULL) l=l->next;
00399 return(l);
00400 }
00401
00402
00403 int TMM_FreeSegList(SegList *list)
00404 {
00405 SegList *l;
00406 if(list==NULL) return(-1);
00407
00408 l=TMM_SeekSegListHead(list);
00409
00410 while(l->next!=NULL)
00411 {
00412 SegList *temp=l->next;
00413 free(l);
00414 l=temp;
00415 }
00416 free(l);
00417 return(0);
00418 }
00419
00420 int TMM_AreaIntersectsSeg(ToySegment *seg1, ToySegment *seg2)
00421 {
00422 int dp=seg2->pos-seg1->pos;
00423
00424 if(dp>0)
00425 {
00426 if(dp>=seg1->len) return(0);
00427 else return(1);
00428 }
00429 else
00430 {
00431 dp=-dp;
00432 if(seg2->len<=dp) return(0);
00433 else return(1);
00434 }
00435 }
00436
00437
00438 int TMM_SubtractSegs(ToySegment *seg1, ToySegment *seg2, ToySegment segOut[2])
00439 {
00440 int dp=seg2->pos-seg1->pos;
00441
00442 if(!TMM_AreaIntersectsSeg(seg1,seg2)) return(-1);
00443
00444 if(dp>0)
00445 {
00446 if(SegEnd(seg2) >= SegEnd(seg1))
00447 {
00448 int olSize=seg1->len-dp;
00449 segOut[0].pos=seg1->pos;
00450 segOut[0].len=seg1->len-olSize;
00451 return(1);
00452 }
00453 else
00454 {
00455 segOut[0].pos=seg1->pos;
00456 segOut[0].len=dp;
00457 segOut[1].pos=SegEnd(seg2);
00458 segOut[1].len=seg1->len-(seg2->len+dp);
00459 return(2);
00460 }
00461 }
00462 else
00463 {
00464 dp=-dp;
00465
00466 if(SegEnd(seg2)>=SegEnd(seg1)) return(0);
00467 else
00468 {
00469 int olSize=seg2->len-dp;
00470 segOut[0].pos=seg1->pos+olSize;
00471 segOut[0].len=seg1->len-olSize;
00472 return(1);
00473 }
00474 }
00475 }