www.pudn.com > buildct.zip > CHAIN.CPP, change:2004-02-24,size:24367b


//for debug 
#include "conio.h" 
//#include <graphics.h>           // For graphics library functions 
#include <stdlib.h>             // For exit() 
#include "StdAfx.h" 
/* 
#ifndef __FILEREADBMP_H 
#include "readBmp.h" 
#endif 
*/ 
//main 
#ifndef __FILECHAIN_H 
#include "chain.h" 
#endif 
 
int ChainNode ::appendNode(ChainNode *node) 
{ 
    if(node==NULL)return 0; 
    ChainNode *q=this; 
    ChainNode *p=q->next; 
    while(p!=NULL && p!=this){ 
        q=p; 
        p=p->next; 
        //如果循环链表,遇到相同结点结束 
    } 
    q->next=node; 
    node->next=p; 
    return 1; 
} 
 
 
 
int ChainNode ::getLinkCount() 
{ 
    ChainNode *current=this->link; 
    int len=1; 
    while(current!=NULL && current!=this){ 
        len++; 
        current=current->link; 
        //如果循环链表,遇到相同结点结束 
 
    } 
    return len; 
} 
int ChainNode ::getNextCount() 
{ 
    ChainNode *current=this->next; 
    int len=1; 
    while(current!=NULL && current!=this){ 
        len++; 
        current=current->next; 
        //如果循环链表,遇到相同结点结束 
 
    } 
    return len; 
} 
 
Chain ::~Chain() 
{//链表的析构函数,用于删除链表中的所有节点 
    erase(); 
} 
 
 
 
/* 
void Chain ::Output(ostream &out)const 
{//将链表元素送至输出流 
ChainNode *current; 
for(current=first;current;current=current->link) 
out<<current->data<<""; 
} 
//重载< 
ostream &operator<<(ostream&out,const Chain &x) 
{x.Output(out);return out;} 
 
*/ 
 
void Chain ::freeNotLinked() 
{ 
    if(first==NULL)return; 
     ChainNode *s,*p,*q=NULL; 
    s=first; 
    do 
    { 
        
        q=s; 
        p=q->getNext(); 
        while(p!=NULL && p!=s){ 
            //if(p->getTag()!=LINKED) 
            if(p->getTag()==NOUSED) 
            { 
		        q->next=p->getNext(); 
                delete(p); 
                p=q->getNext(); 
            } 
            else 
            { 
                q=p; 
                p=p->getNext(); 
            } 
	         
        }; 
       s=s->getLink(); 
        //若循环则结束 
    }while(s!=NULL && s!=first); 
 
} 
 
void Chain ::erase(void) 
{//删除链表中的所有节点 
 
    ChainNode *p,*q; 
    while(first!=NULL){ 
        p=first->link; 
        while(first!=NULL){ 
            q=first->next; 
            delete first; 
            first=q; 
        } 
        first=p; 
    } 
    first=NULL; 
} 
 
 
ChainNode *Chain ::getLast(void) 
{//在链表尾部添加x 
    if(first==NULL)return first; 
    ChainNode *last=first->link; 
    ChainNode *q=first; 
    while(last!=NULL && last !=first){//链表非空 
        q=last; 
        last=last->link; 
    } 
 
    return q; 
} 
 
void Chain::debugPrint(void) 
{ 
    ChainNode *s,*p; 
    if(first==NULL) 
    printf("\nChain is NULL!\n"); 
    s=first; 
    printf("\nthe Chain is:\n"); 
    do 
    { 
	printf("<"); 
        p=s->link; 
        do 
        { 
	    printf("(%d,%d),",s->data.x,s->data.y); 
            s=s->next; 
        }while(s!=NULL && s!=first); 
	static int c=0; 
        if(c++%20==0)getch(); 
	printf("> \n"); 
        s=p; 
        //若循环则结束 
    }while(s!=NULL && s!=first); 
 
 
} 
 
 
Chain &Chain ::append(ChainNode *node) 
{//在链表尾部添加x 
    if(node==NULL)return *this; 
 
    ChainNode * last=getLast(); 
    if(first) 
    {//链表非空 
        last->setLink(node); 
        last=node; 
    } 
    else//链表为空 
    first=node; 
    return *this; 
} 
 
ChainNode *Chain ::getTheHead(int y) 
{ 
    if(first==NULL)return NULL; 
    //ChainNode *p=first->link; 
    ChainNode *p=first; 
    do 
    {//链表非空 
        if(p->getY()==y)break; 
        p=p->link; 
    }while(p!=NULL && p !=first); 
    if(p==NULL || p->getY()!=y)p=NULL; 
    return p; 
} 
ChainNode *Chain ::getPreHead(int y) 
{ 
    ChainNode *q=getTheHead(y); 
    ChainNode *p=NULL; 
    if(q!=NULL)p=q->getBackLink(); 
    return p; 
 
} 
ChainNode *Chain ::getNextHead(int y) 
{ 
    ChainNode *q=getTheHead(y); 
    ChainNode *p=NULL; 
    if(q!=NULL)p=q->getLink(); 
    return p; 
} 
 
/** 
  选择逆时针方向的点 
  if(a1b2-a2b1>0) 
    then (a1,b1) 
  else  
     (a2,b2)   
  end    
 */ 
ChainNode *Chain ::getClockWiseNearer(int x,int y, long &dist2) 
{ 
    long tempdist1,tempdist2; 
    long pointto=0; 
     
    ChainNode * p1=getNearestInChain(x,y,tempdist1); 
    // 
    ChainNode *nearer=p1; 
    dist2=tempdist1; 
     
    if(p1==NULL)return NULL; 
    p1->setTag(MARKED); 
    ChainNode * p2=getNearestInChain(x,y,tempdist2); 
    //回复p1的tag属性 
    p1->setTag(INIT); 
     
    if(p2==NULL)return p1; 
    pointto=(p1->getX()-x)*(p2->getY()-y)-((p2->getX()-x))*((p1->getY()-y)); 
    //取斜率小的 
    long tempdist3=p2->getDistance2(p1->getX(),p1->getY()); 
    if(tempdist3<tempdist1 && tempdist3<tempdist2) 
    { 
        ;//两点的距离足够的小,则取最近的,p1 
    } 
    else if(pointto<0) 
    { 
        nearer=p2; 
        dist2=tempdist2; 
    } 
     
     
    return nearer; 
} 
 
ChainNode *Chain ::getNearestInChain(int x,int y, long &dist2) 
{ 
    long val2=MAX*MAX; 
    ChainNode *nearest=NULL; 
     
    ChainNode *s=first; 
    ChainNode *p=NULL,*q=NULL; 
    do 
    { 
        //若s为空则不处理。 
        if(s==NULL)break; 
        p=s->getLink(); 
        q=s; 
	do 
        {    
            if(q->getTag()==INIT) 
            { 
    		long distance2=q->getDistance2(x,y); 
    		if(distance2=val2) 
                { 
                    val2=distance2; 
                    nearest=q; 
                } 
            } 
            q=q->getNext(); 
        }while(q!=NULL && q!=s); 
        s=p; 
        //若循环则结束 
    }while(s!=NULL && s!=first); 
 
    dist2=val2; 
    if(dist2>BOUND2) 
    { 
        nearest=NULL; 
        dist2=MAX*MAX; 
    } 
    return nearest; 
} 
 
 
int Chain ::linkNearestNodes(ChainNode *start,LineChain *lines) 
{ 
    if(start==NULL) 
    return -1; 
    if(lines==NULL) 
    return -1; 
    /* 
    接力赛的形式从start(q)开始,找到最近点p,再以p为起点,找下一个,直到构成一个闭环 
 
    */ 
    int door=10; 
    long dist2=MAX*MAX; 
    ChainNode *q,*p,*la; 
    q=start; 
    start->setTag(LINKED); 
    //printf("link dist2:"); 
    //int test=0; 
    do 
    { 
    	if(q==NULL)break; 
    	if(q==start)p=getClockWiseNearer(q->getX(),q->getY(),dist2); 
    	else 
    	   p=getNearestInChain(q->getX(),q->getY(),dist2); 
    	//printf("%d,",dist2); 
    	//if(dist2>BOUND2 && q==start)p=NULL; 
    	q->setLink(p); 
    	if(p==NULL)break; 
    	p->setTag(LINKED); 
            //处理下一个 
            la=q; 
            q=p; 
    }while(door-->0 || la->getDistance2(start->getX(),start->getY())>dist2); 
    if(p!=NULL) 
    { 
	la->setLink(start); 
	la->setTag(LINKED); 
    } 
    //long tt= q->getDistance2(start->getX(),start->getY()); 
    //tt=193; 
 
    //printf("tt=%d:dist2=%d (door=%d ,start= %ld ) ",tt,dist2, door,tt); 
 
    lines->append(start); 
    //getch(); 
    return 0; 
} 
 
/* 
int Chain ::postFiltering() 
{ 
    // 
}*/ 
 
//Following is for LineChain 
LineHeader *LineChain::getTheHead(int index) 
{ 
    if(first==NULL|| index>=getCount()|| index<0)return NULL; 
    ChainNode *last=first->getLink(); 
    ChainNode *q=first; 
    int count=0; 
    while(last!=NULL && last !=first){//链表非空 
        if(count>=index) break; 
        count++; 
        q=last; 
        last=last->getLink(); 
    } 
    if(index!=count) 
    {printf("index!=count,%d!=%d",index,count);}; 
    return (LineHeader*)q; 
} 
ChainNode *LineChain::getTheData(int index) 
{ 
    ChainNode *h=getTheHead(index); 
    ChainNode *q=NULL; 
    if(h!=NULL)q=h->getNext(); 
    return q; 
} 
 
 
 
 
LineChain &LineChain ::append(ChainNode *node) 
{ 
    if(node==NULL)return *this; 
 
    LineHeader * tnode=new LineHeader(); 
    tnode->next=node; 
    tnode->setTag(LINEHEAD); 
    ChainNode * last=getLast(); 
    if(last!=NULL){//链表非空 
        last->setLink(tnode); 
        last=node; 
    } 
    else//链表为空 
    first=tnode; 
 
    return *this; 
} 
ChainNode *LineChain ::getLast(void) 
{//在链表尾部添加x 
    if(first==NULL)return first; 
    ChainNode *last=first->link; 
    ChainNode *q=first; 
    while(last!=NULL && last !=first){//链表非空 
        q=last; 
        last=last->link; 
    } 
 
    return (LineHeader*)q; 
} 
void LineChain ::erase(void) 
{//删除链表中的所有节点 
 
    LineHeader *p; 
    while(first!=NULL){ 
        p=(LineHeader*)first->link; 
        delete first; 
        first=p; 
    } 
    first=NULL; 
} 
/** 
  提取轮廓线上的特征点  
  通过两个限定偏差标准:一个为逼近区域的累加面积,另一个为两点连线的 
长度,共同控制特征点的选取. 
  start是轮廓线的出发点,若遇到该点,则提取结束 
*/ 
ChainNode *LineChain::getNearKeyNode(ChainNode *node,ChainNode *start) 
{ 
    if(node==NULL)return NULL; 
    ChainNode *s=node,*p1,*p2; 
    ChainNode *key=NULL; 
    //total为面积2倍绝对值的累加值 
    long total=0; 
 
    do{ 
	    p1=s->getLink(); 
		key=p1; 
        if(p1==start || p1==NULL)break; 
        //p1->setTag(UNUSED); 
        p2=p1->getLink(); 
		key=p2; 
        if(p2==start || p2==NULL)break; 
        total+=node->getTwiceArea(p1,p2); 
		long dist2=p2->getDistance2(node->getX(),node->getY()); 
	    if(total>KEYAREA2||dist2>KEYLENGTH2) 
        { 
             
            //key=p2; 
            break; 
        } 
        s=p1; 
    }while(s!=NULL&&s!=start); 
     
    return key; 
} 
 
ChainNode *LineChain::getFittestLine(ChainNode *line) 
{ 
    if(line==NULL||getCount()==0)return NULL; 
    ChainNode *head=getTheHead(0); 
    long val2=MAX*MAX; 
    ChainNode *fittest=NULL; 
	LineHeader *linehead=(LineHeader*)line; 
	/*if(head->getTag() !=MARKED) 
	{ 
		val2=linehead->getDistance2(head->getX(),head->getY()); 
		fittest=head; 
	}*/ 
    for(int i=0;i<getCount();i++) 
    { 
        LineHeader *head=getTheHead(i); 
	    long dist2=line->getDistance2(head->getX(),head->getY()); 
		bool fine=head->isContained (linehead->getX (),linehead->getY())||linehead->isContained (head->getX (),head->getY ()); 
 
        if(dist2<val2  && fine && head->getTag ()!=MARKED) 
		//if(dist2<val2) 
        { 
            val2=dist2; 
            fittest=head; 
        } 
         
    } 
    return fittest; 
} 
 
 
/*在轮廓线(link的封闭链)中查找最近点,若没有返回NULL*/ 
ChainNode *ChainNode ::getNearestInLink(int x,int y, long &dist2) 
{ 
    //记录距离的平方 
     
	long val2=MAX*MAX; 
    ChainNode *p=NULL; 
    ChainNode *nearest=NULL; 
    p=this; 
    do 
    { 
        if(p==NULL)break; 
        long distance2=p->getDistance2(x,y); 
        if(distance2=val2) 
        { 
            val2=distance2; 
            nearest=p; 
        } 
        p=p->getLink(); 
    }while(p!=NULL && p!=this); 
    dist2=val2; 
	 
		 
    return nearest; 
} 
//检查拓扑完整性 
int LineChain ::checkTopo() 
{ 
    LineHeader *s=first; 
	ChainNode *p; 
    //提取关键点 
    do 
    { 
    	if(s==NULL) 
    	break; 
    	p=s->next; 
	do{ 
		if(p==NULL)break; 
		ChainNode *nextkey=getNearKeyNode(p,s->next); 
	        if(nextkey!=NULL) 
	        { 
	            //设置p到nextkey之间的结点标志为UNUSED 
	            ChainNode *q=p->getLink(); 
	            while(q!=nextkey) 
	            { 
	                q->setTag(NOUSED); 
	                q=q->getLink(); 
	            } 
	            //setUnused(p,nextkey); 
	            p->setLink(nextkey); 
	        } 
    	    p=nextkey; 
    	}while(p!=NULL &&p!=s->next); 
    	s=(LineHeader*)s->getLink(); 
    }while(s!=NULL && s!=first); 
     
    //计算每个轮廓线的中心值,存于轮廓线头结点 
    long totalx=0; 
    long totaly=0; 
    long count=0; 
	 
    s=first; 
    do 
    { 
        if(s==NULL) 
    	break; 
		s->bound.SetRectEmpty (); 
    	p=s->next; 
    	totalx=0; 
        totaly=0; 
        count=0; 
		s->perimeter=0.0; 
        ChainNode *q=NULL; 
    	do{ 
    	    if(p==NULL)break; 
    	    totalx+=p->getX(); 
    	    totaly+=p->getY(); 
			s->bound.UnionRect (&(s->bound),new CRect(p->getX(),p->getY(),p->getX()+1,p->getY()+1)); 
			if(q!=NULL) 
				s->perimeter +=sqrt(p->getDistance2 (q->getX(),q->getY ())); 
    	    count++; 
    	    q=p; 
    	    p=p->getLink(); 
    	}while(p!=NULL &&p!=s->next); 
    	//轮廓线的头结点缺省值为(0,0). 
    	if(count!=0) 
    	{ 
    	    s->setXY((int)(totalx/count),(int)(totaly/count)); 
    	} 
    	//如果轮廓线没有封闭,则封闭 
    	if(q!=NULL) 
    	 q->setLink(s->next); 
    	//循环到下一行 
    	s=(LineHeader*)s->getLink(); 
    }while(s!=NULL && s!=first); 
     
     
     return 0; 
} 
     
   
int Triangle::appendFacet(TriangleFacet *face) 
{ 
    if(face==NULL)return -1; 
    if(first==NULL) 
    { 
        first=face; 
        return 0; 
    } 
    TriangleFacet *q=first,*p=first; 
    while(p!=NULL ){ 
        q=p; 
        p=p->next; 
    } 
    if(q!=NULL) 
        q->next=face; 
    return 0; 
} 
   
Triangle::~Triangle() 
{ 
    TriangleFacet *q=NULL,*p=first; 
    while(p!=NULL ){ 
        q=p->next; 
        delete p; 
        p=q; 
    } 
    
} 
void Triangle::debugPrint() 
{ 
    if(first==NULL) 
    { 
      printf("\n\nTraingle:Empty!\n"); 
      return; 
    } 
    TriangleFacet *p=first; 
    printf("\nTraingle:\n"); 
    //int cc=0; 
    while(p!=NULL ){ 
        printf("<%d,%d,%d %d,%d,%d %d,%d,%d>\n",p->x1,p->y1,p->z1,p->x2,p->y2,p->z2,p->x3,p->y3,p->z3); 
        //if(cc++%20==0)getch(); 
        p=p->next; 
    } 
    printf("\nEnd!\n"); 
} 
void Triangle::printToFile(char *outname) 
{ 
    if(first==NULL)return; 
    FILE *outfile=fopen(outname,"wt"); 
	if(outfile==NULL) 
		return; 
    TriangleFacet *p=first; 
    fprintf(outfile,"Traingle:\n"); 
    while(p!=NULL ){ 
	fprintf(outfile,"<%d,%d,%d %d,%d,%d %d,%d,%d>\n",p->x1,p->y1,p->z1,p->x2,p->y2,p->z2,p->x3,p->y3,p->z3); 
	p=p->next; 
    } 
    fprintf(outfile,"\nEnd!\n"); 
    fclose(outfile); 
} 
         
 
//for debug< 
CString LineChain::simplePrint() 
{ 
	CString rs; 
	CString temp; 
    rs.Format ("\n“+”字符为轮廓线中心。\n轮廓线<%d 条>:",getCount()); 
	for(int i=0;i<getCount();i++) 
    { 
	ChainNode *datahead=getTheData(i); 
    //temp.Format("\n%d(%d,%d),",datahead->getLinkCount(),datahead->getX (),datahead->getY ()); 
	temp.Format("%d,",datahead->getLinkCount()); 
	 
	rs=rs+temp; 
	 /* 
	 ChainNode *q,*p=datahead; 
	do 
	    {   q=p; 
    		p=p->getLink(); 
	    }while(p!=NULL &&p!=datahead); 
	   if(p==NULL) 
	     printf("-<%ld>,",q->getDistance2(datahead->getX(),datahead->getY())); 
	    else 
	     printf("|<%ld>,",q->getDistance2(datahead->getX(),datahead->getY())); 
	   */   
    } 
 
    return rs; 
} 
void LineChain::debugPrint(void) 
{ 
    printf("debug:line chain (nums:%d):",getCount()); 
    for(int i=0;i<getCount();i++) 
      printf("%d,",getTheData(i)->getLinkCount()); 
    printf("\nthe linked line is:\n"); 
    static int c=0; 
    getch(); 
    ChainNode *s=first,*p; 
    do 
    { 
	if(s==NULL) 
	break; 
	p=s->next; 
	if(p!=NULL) 
	{ 
	    printf("<%d:(%d,%d)-",p->getLinkCount(),s->getX(),s->getY()); 
	    do 
	    { 
		printf("(%d,%d)-",p->getX(),p->getY()); 
		p=p->link; 
	    }while(p!=NULL &&p!=s->next); 
	     
	    if(c++%15==0)getch(); 
	    if(p==NULL) 
		printf(">->\n"); 
	    else 
		printf(">||\n"); 
	} 
	s=s->getLink(); 
    }while(s!=NULL && s!=first); 
 
} 
 
int LineChain::graphicsDebugPrint(CBitmap *pBmp) 
{ 
	if(pBmp==NULL) 
		return -1; 
	CDC dcMem; 
	dcMem.CreateCompatibleDC(NULL);//这里我们就在内存中虚拟建造了DC 
	pBmp->DeleteObject(); 
	pBmp->CreateCompatibleBitmap(&dcMem,IMAGEW,IMAGEH);//依附DC创建bitmap 
	CBitmap *pOldBitmap = dcMem.SelectObject(pBmp);//我们调入了我们bitmap目标 
    CPen newPen(PS_SOLID, 1, RGB(255,255,255)); 
	CPen *oldPen=dcMem.SelectObject(&newPen);  
//	dcMem.LineTo ( 
	ChainNode *s=first,*p; 
	do 
    { 
    	if(s==NULL) 
    	break; 
    	p=s->next; 
    	if(p!=NULL) 
    	{ 
	    //printf("<%d:(%d,%d)-",p->getLinkCount(),p->getX(),p->getY()); 
	    //setcolor(color++); 
    	    //if(color>15)color=0; 
	        dcMem.Ellipse (p->getX()-3,p->getY()-3,p->getX()+3,p->getY()+3);// circle(p->getX(),p->getY(),3); 
	        dcMem.MoveTo (p->getX(),p->getY()); 
	  	    do 
    	    { 
        		//printf("(%d,%d)-",p->getX(),p->getY()); 
        		dcMem.LineTo(p->getX(),p->getY()); 
        		p=p->link; 
    	    }while(p!=NULL &&p!=s->next); 
        
    	  if(p==NULL) 
	       { 
	         
			CPoint point=dcMem.GetCurrentPosition (); 
			int cx=point.x; 
	        int cy=point.y; 
			// line(cx-3,cy,cx+3,cy); 
			dcMem.MoveTo (cx-3,cy); 
	        dcMem.LineTo (cx+3,cy); 
			//line(cx,cy-3,cx,cy+3); 
			dcMem.MoveTo (cx,cy-3); 
	        dcMem.LineTo (cx,cy+3); 
	       } 
		  //画中心 
		  //if(s->getX ()!=0 && s->getY ()!=0) 
		  {	 
			int cx=s->getX (); 
	        int cy=s->getY (); 
			// line(cx-3,cy,cx+3,cy); 
			dcMem.MoveTo (cx-3,cy); 
	        dcMem.LineTo (cx+3,cy); 
			//line(cx,cy-3,cx,cy+3); 
			dcMem.MoveTo (cx,cy-3); 
	        dcMem.LineTo (cx,cy+3); 
			} 
    	} 
    	s=s->getLink(); 
    }while(s!=NULL && s!=first); 
 
 
	// 
	dcMem.SelectObject(oldPen); 
	dcMem.SelectObject(pOldBitmap); 
	dcMem.DeleteDC(); 
	return 0; 
} 
int Triangle::graphicsDebugPrint(CBitmap *pBmp,int type) 
{ 
	if(pBmp==NULL) 
		return -1; 
	CDC dcMem; 
	dcMem.CreateCompatibleDC(NULL);//这里我们就在内存中虚拟建造了DC 
	pBmp->DeleteObject(); 
	pBmp->CreateCompatibleBitmap(&dcMem,IMAGEW,IMAGEH);//依附DC创建bitmap 
	CBitmap *pOldBitmap = dcMem.SelectObject(pBmp);//我们调入了我们bitmap目标 
    CPen newPen(PS_SOLID, 1, RGB(255,255,255)); 
	CPen *oldPen=dcMem.SelectObject(&newPen);  
     
	TriangleFacet *p=first; 
//	int cc=0; 
    //int cc=0; 
    while(p!=NULL ){ 
        drawFacet(p,&dcMem,type); 
		//if(cc++%20==0)getch(); 
        p=p->next; 
	//	cc++; 
    } 
	// 
	dcMem.SelectObject(oldPen); 
	dcMem.SelectObject(pOldBitmap); 
	dcMem.DeleteDC(); 
 
	return 0; 
} 
 
CString Triangle::simplePrint() 
{ 
	CString rs; 
	CString temp; 
    rs.Format ("三角表面体(z轴放大3倍):"); 
 
    TriangleFacet *p=first; 
	int cc=0; 
    //int cc=0; 
    while(p!=NULL ){ 
        //printf("<%d,%d,%d %d,%d,%d %d,%d,%d>\n",p->x1,p->y1,p->z1,p->x2,p->y2,p->z2,p->x3,p->y3,p->z3); 
        //if(cc++%20==0)getch(); 
        p=p->next; 
		cc++; 
    } 
    temp.Format ("%d个三角片。",cc); 
	rs=rs+temp; 
    return rs; 
} 
 
//for graphics debug 
/* 
int max_x, max_y;           // Maximum x- and y-coordinates 
 
int set_graph(void) 
{ 
	int graphdriver = DETECT, graphmode, error_code; 
 
	//Initialize graphics system; must be EGA or VGA 
	initgraph(&graphdriver, &graphmode, "d:\\programs\\tc3\\bgi"); 
	error_code = graphresult(); 
	if (error_code != grOk) 
	{	 
	    printf("error_code=%d!",error_code); 
	    return(-1); 
    }               // No graphics hardware found 
	if ((graphdriver != EGA) && (graphdriver != VGA)) 
	{ 
		closegraph(); 
		return 1; 
	} 
	return(0);                   // Graphics OK, so return "true" 
} 
void calc_coords(void) 
{ 
	// Set global variables for drawing 
	max_x = getmaxx();           // Returns maximum x-coordinate 
	max_y = getmaxy();           // Returns maximum y-coordinate 
	//char a[100]; 
	//sprintf(a,"max(%d*%d)",max_x,max_y); 
	//outtextxy(10,10,a); 
} 
void get_key(void) 
{ 
	outtextxy(50, max_y - 20, "Press any key to exit"); 
	getch(); 
} 
//outtextxy(50, max_y - 20, "Press any key to exit"); 
int LineChain::graphicsDebugPrint() 
{ 
    // Exit if not EGA or VGA 
	// Find out if they have what it takes 
	if (set_graph() != 0) { 
		printf("This program requires EGA or VGA graphics\n"); 
		return -1; 
	} 
	calc_coords();       // Scale to graphics resolution in use 
	//draw_planets();      // Sun through Uranus  
	char a[100]; 
	static int cc=1; 
	sprintf(a,"NO %d, line chain (nums:%d):",cc++,getCount()); 
	outtextxy(0,10,a); 
    for(int i=0;i<getCount();i++) 
    { 
          sprintf(a,"%d,",getTheData(i)->getLinkCount()); 
	  outtextxy(i*30+220,10,a); 
    }   
    int color=1; 
	ChainNode *s=first,*p; 
    do 
    { 
    	if(s==NULL) 
    	break; 
    	p=s->next; 
    	if(p!=NULL) 
    	{ 
	    //printf("<%d:(%d,%d)-",p->getLinkCount(),p->getX(),p->getY()); 
	    setcolor(color++); 
    	    if(color>15)color=0; 
	    circle(p->getX(),p->getY(),3); 
	    moveto(p->getX(),p->getY()); 
	  	    do 
    	    { 
        		//printf("(%d,%d)-",p->getX(),p->getY()); 
        		lineto(p->getX(),p->getY()); 
        		p=p->link; 
    	    }while(p!=NULL &&p!=s->next); 
        
    	  if(p==NULL) 
	       { 
	        int cx=getx(); 
	        int cy=gety(); 
	        line(cx-3,cy,cx+3,cy); 
	        line(cx,cy-3,cx,cy+3); 
	       } 
    	} 
    	s=s->getLink(); 
    }while(s!=NULL && s!=first); 
	 
	// 
	get_key();           // Display message and wait for key press 
	closegraph();        // Close graphics system 
	return 0; 
}	 
 
//for graphics debug 
int graphicsBufferPrint(unsigned char data[][IMAGEW/8]) 
{ 
    // Exit if not EGA or VGA 
	// Find out if they have what it takes 
	if (set_graph() != 0) { 
		printf("This program requires EGA or VGA graphics\n"); 
		return -1; 
	} 
	calc_coords();       // Scale to graphics resolution in use 
	//draw_planets();      // Sun through Uranus  
	int color=1; 
	setcolor(color++); 
    if(color>15)color=0; 
     
	for(int i=0;i<IMAGEH;i++) 
    { 
        //printf("\n"); 
        for(int j=0;j<IMAGEW/8;j++) 
        { 
	   for(int k=0;k<8;k++) 
	   if(getValue(data,j*8+k,i)==1) 
	    putpixel(j*8+k,i,color);// printf(" %d",getValue(buffer,j*8+k,i)); 
	} 
    } 
	// 
	get_key();           // Display message and wait for key press 
	closegraph();        // Close graphics system 
	return 0; 
}	 
 
//>>for debug 
 
  */ 
 
void Triangle::setAvailable(bool avail) 
{ 
   available=avail; 
} 
 
bool Triangle::isAvailable() 
{ 
	return available; 
 
} 
/* 
---- 对 物 体 得 任 意 表 面, 可 将 其 划 分 为 若 干 个 平 面, 在 根 据 平 面 上 任 意 三 点 的 坐 标 可 以 求 得 其 平 面 方 程。 标 准 得 平 面 方 程 为  
 
Ax+By+Cz+D = 0; 
---- 其 中A、B、C、D 为 决 定 平 面 得 常 数。 如 果(x1, y1, z1)、(x2, y2, z2)、(x3, y3, z3) 为 平 面 上 已 知 得 三 点 坐 标, 则 可 求 得A、B、C、D 如 下:  
 
{ A=y1(x2-x3)+y2(z3-z1)+y3(z1-z2); 
B=z1(x2-x3)+z2(x3-x1)+z3(x1-x2); 
C=x1(y2-y3)+x2(y3-y1)+x3(y1-y2); 
D=-x1(y2z3-y3z2)-x2(y3z1-y1z3)-x3(y1z2-y2z1);  
 
 
---- 设 观 察 点 坐 标 为(x, y, z), 如 果  
 
Ax+By+Cz+D = 0, 则 观 察 点(x, y, z) 位 于 平 面 上;  
 
Ax+By+Cz+D > 0, 则 观 察 点(x, y, z) 位 于 平 面 背 面 一 侧, 平 面 不 可 见, 应 被 隐 藏;  
 
Ax+By+Cz+D  0, 则 观 察 点(x, y, z) 位 于 平 面 正 面 一 侧, 平 面 是 可 见 面, 应 被 画 出。 
 
 
*/ 
bool Triangle::drawFacet(TriangleFacet *facet, CDC *pdc,int type) 
{ 
  //printf("<%d,%d,%d %d,%d,%d %d,%d,%d>\n",p->x1,p->y1,p->z1,p->x2,p->y2,p->z2,p->x3,p->y3,p->z3); 
      // /*  
	   // long pointto=(p1->getX()-x)*(p2->getY()-y)-((p2->getX()-x))*((p1->getY()-y)); 
    	//int color=(p->z1 +p->z2 +p->z3 )*255/37; 
		//CPen newPen(PS_SOLID, 1, RGB(color,color,color)); 
	   // CPen *oldPen=pdc->SelectObject(&newPen);  
	   int x1,y1,z1,x2,y2,z2,x3,y3,z3; 
	    x1=facet->x1; 
        y1=facet->y1; 
        z1=facet->z1; 
        x2=facet->x2; 
        y2=facet->y2; 
        z2=facet->z2; 
        x3=facet->x3; 
        y3=facet->y3; 
        z3=facet->z3; 
        int xx1,yy1,xx2,yy2,xx3,yy3; 
		int viewx=255,viewy=255,viewz=19*3; 
		bool visual=false; 
        switch(type) 
		{ 
		case	0: 
		case	1: 
			  xx1=y1 ; 
			  xx2=y2; 
			  xx3=y3; 
			  yy1=z1 ; 
			  yy2=z2; 
			  yy3=z3; 
			  viewx=1000; 
			  if(type==2) viewx=-1000; 
			  break; 
		case	2: 
        case	3: 
			  xx1=x1 ; 
			  xx2=x2; 
			  xx3=x3; 
			  yy1=z1 ; 
			  yy2=z2; 
			  yy3=z3; 
			  viewy=1000; 
			  if(type==3)viewy=-1000; 
			  break; 
        case	4: 
		case    5: 
			  xx1=x1 ; 
			  xx2=x2; 
			  xx3=x3; 
			  yy1=y1 ; 
			  yy2=y2; 
			  yy3=y3; 
			  viewz=1000; 
			  if(type==5)viewz=-1000; 
			  break; 
        default: 
			 AfxMessageBox("drawFacet 类型不合法!",0,0); 
		} 
	    long A,B,C,D; 
		A=y1*(x2-x3)+y2*(z3-z1)+y3*(z1-z2); 
		B=z1*(x2-x3)+z2*(x3-x1)+z3*(x1-x2); 
		C=x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2); 
		D=-x1*(y2*z3-y3*z2)-x2*(y3*z1-y1*z3)-x3*(y1*z2-y2*z1); 
 
        long ff=A*viewx+B*viewy+C*viewz+D; 
        visual=ff=0?true:false; 
		if(visual) 
		{ 
			pdc->MoveTo (xx1,yy1); 
			pdc->LineTo (xx2,yy2); 
			pdc->LineTo (xx3,yy3); 
			pdc->LineTo (xx1,yy1); 
		} 
       	return visual; 
}