TIN文件

在这里插入图片描述
在这里插入图片描述

/*
四种数据结构都采用链表存储结构,文件输入输出都使用格式化输入
输出fscanf、fprintf.四个表都设置全局头结点

fun函数:
对于三角形表,三个顶点两两组合成三条边,用每次组合出的边生成
边表与边序号三角形表:每组合出一条边便到扔到cheak函数里去建立
边,每进去一条边要返回一个边编号,返回的边编号恰好能用来为边
序号三角形表赋值

cheak函数里去建立边过程:
三角形一个边的两个点进来后查找边表里是否有对应边,若有,
则为边表第二个三角形编号赋值,并返回这个边编号给三角形2
若没有,则新生成一个边结点,为边结点第一个三角形编号,
并返回这个边编号给三角形2

找边界线
先把边界线存到数组array,接着,任选某条边的一个顶点,另一个
顶点必然是下一个顶点第一个边,依次循环

测试数据(即边表、三角形表文件格式):
9
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9
7 8 9 10
8 9 10 11
10
0 0 1 2
1 0 2 3
2 1 7 2
3 2 4 3
4 2 4 5
5 2 5 7
6 3 4 6
7 4 5 6
8 5 6 8
9 5 7 8
*/

#include <stdlib.h>
#include <stdio.h>
#define maxsize 100
///点
typedef struct point
{
    int point_tag;//点编号
    double x;
    double y;
    double z;
    struct point *next;
} point;


///三角形
typedef struct Tri
{
    int Tri_tag;//三角形编号
    int point1_tag;
    int point2_tag;
    int point3_tag;
    struct Tri *next;
} Tri;


///边
typedef struct Arc
{
    int e_tag;//边编号
    int point1_tag;
    int point2_tag;
    int Tri_tag1;
    int Tri_tag2;
    struct Arc *next;
} Arc;

///三角形2
typedef struct Tri_new
{
    int Tri_new_tag;//三角形编号
    int Tri_new_e1;//第一条边编号
    int Tri_new_e2;//第二条边编号
    int Tri_new_e3;//第三条边编号
    struct Tri_new *next;
} Tri_new;


point *P;//点链表头结点
Tri *T;//三角形链表头结点
Arc *E;//边链表头结点
Tri_new *TT;//边链表头结点

///为四个表表头分配空间,并初始化表头标号-1
void creat_head()
{
    P=(point *)malloc(sizeof(point));
    P->next=NULL;
    P->point_tag=-1;

    T=(Tri *)malloc(sizeof(Tri));
    T->next=NULL;
    T->Tri_tag=-1;

    E=(Arc *)malloc(sizeof(Arc));
    E->next=NULL;
    E->e_tag=-1;

    TT=(Tri_new *)malloc(sizeof(Tri_new));
    TT->next=NULL;
    TT->Tri_new_tag=-1;
}

FILE *fp;
///初始化顶点表
void creat_Point()
{
    point *r=P;
    int num_point,i;
    fp=fopen("data.txt","r");
    fscanf(fp,"%d",&num_point);
    printf("点:\n");
    for(i=0; i<num_point; i++)
    {
        point *p=(point *)malloc(sizeof(point));
        fscanf(fp,"%d %lf %lf %lf",&(p->point_tag),&(p->x),&(p->y),&(p->z));
        printf("%d %.2f %.2f %.2f\n",(p->point_tag),(p->x),(p->y),(p->z));
        //p->point_tag=i;
        r->next=p;
        r=p;
    }
    r->next=NULL;

}

///初始化三角形表
void creat_Tri()
{
    Tri *r=T;
    int num_Tri,i;
    fscanf(fp,"%d",&num_Tri);
    printf("\n三角形:\n");
    for(i=0; i<num_Tri; i++)
    {
        Tri *p=(Tri *)malloc(sizeof(Tri));
        fscanf(fp,"%d %d %d %d",&(p->Tri_tag),&(p->point1_tag),&(p->point2_tag),&(p->point3_tag));
        printf("%d %d %d %d\n",(p->Tri_tag),(p->point1_tag),(p->point2_tag),(p->point3_tag));
        //p->Tri_tag=i;
        r->next=p;
        r=p;
    }
    r->next=NULL;

}


/*三角形一个边的两个点进来后查找边表里是否有对应边,若有,
则为边表第二个三角形编号赋值,并返回这个边编号给三角形2
若没有,则新生成一个边结点,为边结点第一个三角形编号,
并返回这个边编号给三角形2*/
int cheak(int a,int b,int Tri_tag)
{

    Arc *p=E;
    Arc *ee=NULL;
    while(p->next!=NULL)
    {
        if((p->next->point1_tag==a&&p->next->point2_tag==b)||(p->next->point1_tag==b&&p->next->point2_tag==a))//说明该边已建立
        {
            p->next->Tri_tag2=Tri_tag;
            //printf("边出:%d\n",p->next->e_tag);
            return p->next->e_tag;
            break;
        }
        p=p->next;
    }
    if(p->next==NULL)////说明该边还没建立
    {
        ee=(Arc *)malloc(sizeof(Arc));
        ee->next=NULL;
        ee->point1_tag=a;
        ee->point2_tag=b;
        ee->e_tag=(p->e_tag)+1;//下一个结点编号为上一个结点编号加1
        ee->Tri_tag1=Tri_tag;
        ee->Tri_tag2=-1;

        p->next=ee;//把生成的新节点连到边表中
        //printf("边出:%d\n",ee->e_tag);
        return ee->e_tag;
    }
    return 111;
}

/*对于三角形表,三个顶点两两组合成一条边,用每次组合出的边生成边表与边序号三角形
表:每组合出一条边便到扔到cheak函数里去建立边,每进去一条边当然要返回一个边编号,
返回的边编号恰好能用来为边序号三角形表赋值
*/
void fun()
{
    T=T->next;
    Tri_new *r=TT;
    while(T)
    {
        Tri_new * tt=(Tri_new *)malloc(sizeof(Tri_new));
        tt->Tri_new_tag=(r->Tri_new_tag)+1;

        tt->Tri_new_e1=cheak(T->point1_tag,T->point2_tag,T->Tri_tag);

        tt->Tri_new_e2=cheak(T->point1_tag,T->point3_tag,T->Tri_tag);

        tt->Tri_new_e3=cheak(T->point2_tag,T->point3_tag,T->Tri_tag);

        T=T->next;
        ///尾插
        r->next=tt;
        r=tt;
    }
    r->next=NULL;
}

///把边表,边序号三角形写入到文件
void write()
{
    FILE *fb=fopen("result.txt","w");

    Arc *p=E->next;//边
    Tri_new *q=TT->next;//三角形
    printf("边:\n");
    while(p)
    {
        ///五个数据
        fprintf(fb,"%d %d %d %d %d\n",p->e_tag,p->point1_tag,p->point2_tag,p->Tri_tag1,p->Tri_tag2);
        printf("%d %d %d %d %d\n",p->e_tag,p->point1_tag,p->point2_tag,p->Tri_tag1,p->Tri_tag2);
        p=p->next;
    }
    fprintf(fb,"\n");
    printf("边序号三角形:\n");
    while(q)
    {
        ///四个数据
        fprintf(fb,"%d %d %d %d\n",q->Tri_new_tag,q->Tri_new_e1,q->Tri_new_e2,q->Tri_new_e3);
        printf("%d %d %d %d\n",q->Tri_new_tag,q->Tri_new_e1,q->Tri_new_e2,q->Tri_new_e3);
        q=q->next;
    }


}

///找边界线函数,先把边界线存到数组array,再从数组中把边界线点找出输出
void find_line()
{
    Arc array[maxsize];
    int top=-1;
    Arc *p=E->next;
    while(p)
    {
        if(p->Tri_tag2==-1)
        {
            array[++top]=*p;
        }
        p=p->next;
    }

    printf("找边界点\n");

    int i,tag,n=top;//tag用来存储当前边没被输出的那个点,同时也一定是下一条边界线起点

    printf("%d->",array[0].point1_tag);//以第一条边第一个点为起点
    tag=array[0].point2_tag;//当前边的第二个点,同时也一定是第二条边界线起点

    ///把已经找到的边置为-1,是为了下一次搜索跳过它
    array[0].point1_tag=-1;
    array[0].point2_tag=-1;
    while(top!=0)//还有1~top之间边搜索
    {
        for(i=0; i<=n; i++)
        {
            if(array[i].point1_tag==tag)
            {
                printf("%d->",array[i].point1_tag);
                tag=array[i].point2_tag;

                array[i].point1_tag=-1;
                array[i].point2_tag=-1;
                break;
            }
            if(array[i].point2_tag==tag)
            {
                printf("%d->",array[i].point2_tag);
                tag=array[i].point1_tag;

                array[i].point1_tag=-1;
                array[i].point2_tag=-1;
                break;
            }
        }
        top--;
    }


}

int main()
{
    ///初始化四个链表顶点表、三角形表、边表、边序列三角形表的头结点
    creat_head();

    ///从文件读取顶点表
    creat_Point();
    ///从文件读取三角形表
    creat_Tri();

    ///构建边表、边序列三角形表
    fun();

    ///将边表、边序列三角形表输入到文件
    write();
    printf("已输出至文件result.txt!\n\n");

    ///找边界线
    find_line();
}

猜你喜欢

转载自blog.csdn.net/weixin_42034217/article/details/84950950