/* 程序实现的算法: 用链表来存储边的信息
用 边的数量来判定 边的方位。
*/
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#define Left 0 // 方向常量
#define Right 1
#define Bottem 2
#define fcolor 1
#define bkcolor 0
#define N 10
#define PD M_PI/180
typedef struct Point// 定义节点
{
float x;
float y;
}Point;
typedef struct Elegs// 定义边
{
Point a;
Point b;
struct Elegs *next;
}Elegs;
Elegs *head;
int n = 0 , Trend;// Trend 方向性 指示变量, n为边的总数
/*函数说明*/
void Init();
void Init_draw(int x,int y,int len ,int du);// 初始化 画三角形
void Draw(Point a,Point b,int du , int bool);// 具体实现画边
void Check_trand(int i); // 检测边的方向性
void show(Elegs *head,int du);// 链表用以动态存储 边的信息
void End();
Elegs *New();
Elegs *Add(Elegs *head,Point a,Point b);
Elegs *freelink(Elegs *head);
void Init()
{
int gd=DETECT,gm,ec;
Elegs *p;
initgraph(&gd,&gm,"d:\\tc3\\bgi");
ec = graphresult();
if(ec !=grOk)
{
printf("The graphic error:");
printf("%s ",grapherrormsg(ec));
printf("Key any to halt:");
getch();
exit(0);
}
setbkcolor(bkcolor);
setcolor(fcolor);
Trend = 0;
p = New();
head = p;
p->next = NULL;
};// Init
void Init_draw (int x,int y,int len, int du)
{
int x1,x2,y1,y2;
Point a,b,c;
Elegs *p;
x1 = x - len* cos((60+du)*M_PI/180);
y1 = y + len* sin((60+du)*M_PI/180);
line(x,y,x1,y1);
x2 = x - len* cos((120+du)*M_PI/180);
y2 = y + len* sin((120+du)*M_PI/180);
line(x,y,x2,y2);
line(x1,y1,x2,y2);
a.x = x; a.y = y;
b.x = x1; b.y = y1;
c.x = x2; c.y = y2;
Add(head ,a ,b);
Add(next ,b ,c);
Add(next ,c ,a);
}// Init_draw();
Elegs *New(void)
{
Elegs *p;
p = (Elegs*)malloc(sizeof(Elegs));
if(p ==NULL)
{printf("the malloc the memory is wrong:\nPlease Key any to halt:");
getch();
exit(0);
}
p->next = NULL;
return p;
}// *New
Elegs *Add(Elegs *hd, Point a,Point b)
{
Elegs *p1;
p1 = New();
(p1->a).x = a.x; (p1->a).y = a.y;
(p1->b).x = b.x; (p1->b).y = b.y;
p1->next = NULL;
hd->next =p1;
next = p1; n++;
}// *Add()
Elegs *freelink( Elegs *hd)
{
Elegs *p1,*p2;
p1 = hd;
while(p1->next != NULL)
{
p2 = p1->next;
free(p1);
p1 = p2;
}
}// *freelink();
void Draw(Point a, Point b,int du ,int bool)
{
Point Firstp,Secondp,Minp ;
double eleg,e;
double dx,dy;
dx = abs(a.x-b.x);
dy = abs(a.y -b.y);
eleg = sqrtl( dx*dx + dy*dy );
Firstp.x = (a.x*2 + b.x)/3; // 3等分点
Firstp.y = (a.y*2 + b.y)/3;
Secondp.x = (a.x + 2* b.x)/3 ;
Secondp.y = (a.y + 2* b.y)/3 ;
e = eleg * 0.58;
if (bool == Left )
{
if (Trend ==Left)
{Minp.x = a.x - e *cos((30+du)*PD);
Minp.y = a.y + e *sin((30+du)*PD);}
else
{Minp.x = a.x + e *cos((30+du)*PD);
Minp.y = a.y - e *sin((30+du)*PD);}
}
if (bool == Bottem )
{
if (Trend == Bottem)
{Minp.x = a.x + e*cos((30-du)*PD);
Minp.y = a.y + e*sin((30-du)*PD);}
else
{Minp.x = a.x - e*cos((30-du)*PD);
Minp.y = a.y - e*sin((30-du)*PD);}
}
if (bool == Right )
{ if ( Trend == Right )
{Minp.x = a.x - e*sin(du*PD);
Minp.y = a.y - e*cos(du*PD);}
else
{Minp.x = a.x + e*sin(du*PD);
Minp.y = a.y + e*cos(du*PD);}
}
line(Firstp.x , Firstp.y , Minp.x , Minp.y );
line(Secondp.x , Secondp.y , Minp.x , Minp.y );
// 除中间的一段线
setcolor(bkcolor);
setlinestyle(0,1,3);
line(Firstp.x, Firstp.y , Secondp.x, Secondp.y);
setlinestyle(0,1,1);
setcolor(fcolor);
n += 4;
Add (next, a , Firstp);
Add (next, Firstp, Minp);
Add (next, Minp , Secondp);
Add (next, Secondp, b);
}// draw
void Check_trend(int x) // 根据边的数量来判定 边的方位
{
int story=0; // 到了第几层
int l1,l2,b1,b2,r1,r2;
/* l1是 左边的第一个点, l2是左边的第二个点
b1是底边的第一个点, b2是底边的第二个点
r1是右边的第一个点 r2是右边的第二个点*/
while(1)
{
story ++;
l1 = pow(4,story)-1;
r2 = 4*pow(4,story)-2;
if( (x>= l1) &&(x<= r2) )
{
l2 = l1*2;
b1 = l2+1;
b2 = b1+l1;
r1 = b2+1;
if( x>=l1 && x<=l2)
Trend= Left;
if( x>=b1 && x<=b2)
Trend = Bottem;
if( x>=r1 && x<=r2)
Trend = Right;
break;
}
} }
void Onshow(int du)
{
Elegs *s,*t;
int i = 3,story=0;
s = head;
// 画第一层;
s= s->next; Trend = Left;
Draw( s->a, s->b ,du,Left);
s = s->next; Trend = Bottem;
Draw( s->a, s->b ,du,Bottem);
s = s->next; Trend = Right;
Draw( s->a, s->b ,du,Right);
while( (s->next != NULL)&&( (n-i)>=3 ) )
{
s = s->next; Check_trend(i++);
Draw( s->a, s->b ,du,Left);
s = s->next; Check_trend(i++);
Draw( s->a, s->b ,du,Bottem);
s = s->next; Check_trend(i++);
Draw( s->a, s->b ,du,Right);
story ++;
if(story ==20) // 限制层次
break;
}
}
void End()
{
getch();
freelink(head);
closegraph();
}
void main()
{
int du=45; // 三角形的旋转幅度
Init();
Init_draw(320,120,200,du);
Onshow(du);
End();
}
/* 程序有不完善的地方
当 story 调高时,有一边方位有错;
方位可否用向量来判定,还请你们请教。
Word教程网 | Excel教程网 | Dreamweaver教程网 | Fireworks教程网 | PPT教程网 | FLASH教程网 | PS教程网 |
HTML教程网 | DIV CSS教程网 | FLASH AS教程网 | ACCESS教程网 | SQL SERVER教程网 | C语言教程网 | JAVASCRIPT教程网 |
ASP教程网 | ASP.NET教程网 | CorelDraw教程网 |