⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 line3d.c

📁 frasr200的win 版本源码(18.21),使用make文件,使用的vc版本较低,在我的环境下编译有问题! 很不错的分形程序代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
					if (ferror (File_Ptr1))
					{
						fclose (File_Ptr1);
						remove (light_name);
						File_Error(ray_name, 2);
						EXIT_OVLY;
						return(-1);
					}
				}
			}
		
			col++;

		}  /*  End of while statement for plotting line  */

	RO++;

reallythebottom:
		
	/* stuff that HAS to be done, even in preview mode, goes here */	
	if(SPHERE)	
	{	
		/* incremental sin/cos phi calc */	
		if(currow == 0)	
		{	
			sinphi = oldsinphi2;	
			cosphi = oldcosphi2;	
		}	
		else	
		{	
			sinphi = twocosdeltaphi*oldsinphi2 - oldsinphi1;	
			cosphi = twocosdeltaphi*oldcosphi2 - oldcosphi1;	
			oldsinphi1 = oldsinphi2;	
			oldsinphi2 = sinphi;	
			oldcosphi1 = oldcosphi2;	
			oldcosphi2 = cosphi;	
		}	
	}
	EXIT_OVLY;
	return(0); /* decoder needs to know all is well !!! */
}


/* vector version of line draw */
static void _fastcall vdraw_line(v1,v2,color)
double *v1,*v2;
int color;
{
	int x1,y1,x2,y2;
	x1 = (int)v1[0];
	y1 = (int)v1[1];
	x2 = (int)v2[0];
	y2 = (int)v2[1];
	draw_line(x1,y1,x2,y2,color);
}



static void corners(m,show,pxmin,pymin,pzmin,pxmax,pymax,pzmax)

MATRIX m;
int show; /* turns on box-showing feature */
double *pxmin,*pymin,*pzmin,*pxmax,*pymax,*pzmax;

{
	int i,j;
	VECTOR S[2][4]; /* Holds the top an bottom points, S[0][]=bottom */

	/*
	define corners of box fractal is in in x,y,z plane
	"b" stands for "bottom" - these points are the corners of the screen
	in the x-y plane. The "t"'s stand for Top - they are the top of
	the cube where 255 color points hit.
	*/

	*pxmin = *pymin = *pzmin = (int)INT_MAX;
	*pxmax = *pymax = *pzmax = (int)INT_MIN; 

	for (j = 0; j < 4; ++j)
		for (i=0;i<3;i++)
			S[0][j][i]=S[1][j][i]=0;

	S[0][1][0] = S[0][2][0] = S[1][1][0] = S[1][2][0] = xdots-1;
	S[0][2][1] = S[0][3][1] = S[1][2][1] = S[1][3][1] = ydots-1;
	S[1][0][2] = S[1][1][2] = S[1][2][2] = S[1][3][2] = zcoord-1;

	for (i = 0; i < 4; ++i)
	{
		/* transform points */
		vmult(S[0][i],m,S[0][i]);
		vmult(S[1][i],m,S[1][i]);

		/* update minimums and maximums */
		if (S[0][i][0] <= *pxmin) *pxmin = S[0][i][0];
		if (S[0][i][0] >= *pxmax) *pxmax = S[0][i][0];
		if (S[1][i][0] <= *pxmin) *pxmin = S[1][i][0];
		if (S[1][i][0] >= *pxmax) *pxmax = S[1][i][0];
		if (S[0][i][1] <= *pymin) *pymin = S[0][i][1];
		if (S[0][i][1] >= *pymax) *pymax = S[0][i][1];
		if (S[1][i][1] <= *pymin) *pymin = S[1][i][1];
		if (S[1][i][1] >= *pymax) *pymax = S[1][i][1];
		if (S[0][i][2] <= *pzmin) *pzmin = S[0][i][2];
		if (S[0][i][2] >= *pzmax) *pzmax = S[0][i][2];
		if (S[1][i][2] <= *pzmin) *pzmin = S[1][i][2];
		if (S[1][i][2] >= *pzmax) *pzmax = S[1][i][2];
	}

	if(show)
	{
		if(persp)
		{
			for (i=0;i<4;i++)
			{
				perspective(S[0][i]);
				perspective(S[1][i]);
			}
		}

		/* Keep the box surrounding the fractal */
		for (j=0;j<2;j++)
			for (i = 0; i < 4; ++i)
			{
				S[j][i][0] += xxadjust;
				S[j][i][1] += yyadjust;
			}

		draw_rect(S[0][0],S[0][1],S[0][2],S[0][3],2,1);/* Bottom */

		draw_rect(S[0][0],S[1][0],S[0][1],S[1][1], 5, 0); /* Sides */
		draw_rect(S[0][2],S[1][2],S[0][3],S[1][3], 6, 0);

		draw_rect(S[1][0],S[1][1],S[1][2],S[1][3],8,1); /* Top */
	}
}



/* This function draws a vector from origin[] to direct[] and a box
	around it. The vector and box are transformed or not depending on
	FILLTYPE.

*/

static void draw_light_box (origin, direct, light_m)
double *origin, *direct;
MATRIX light_m;


{
	VECTOR S[2][4];
	int i,j;
	double temp;

	S[1][0][0] = S[0][0][0] = origin[0];
	S[1][0][1] = S[0][0][1] = origin[1];

	S[1][0][2] = direct[2];

	for (i=0;i<2;i++)
	{
		S[i][1][0] = S[i][0][0];
		S[i][1][1] = direct[1];
		S[i][1][2] = S[i][0][2];
		S[i][2][0] = direct[0];
		S[i][2][1] = S[i][1][1];
		S[i][2][2] = S[i][0][2];
		S[i][3][0] = S[i][2][0];
		S[i][3][1] = S[i][0][1];
		S[i][3][2] = S[i][0][2];
	}

	/* transform the corners if necessary */
	if (FILLTYPE == 6)
		for (i=0;i<4;i++)
		{
			vmult (S[0][i],light_m,S[0][i]);
			vmult (S[1][i],light_m,S[1][i]);
		}

	/* always use perspective to aid viewing */
	temp = view[2]; /* save perspective distance for a later restore */
	view[2] = - P * 300.0 / 100.0;

	for (i=0;i<4;i++)
	{
		perspective(S[0][i]);
		perspective(S[1][i]);
	}
	view[2] = temp; /* Restore perspective distance*/

	/* Adjust for aspect */
	for (i=0;i<4;i++)
	{
		S[0][i][0] = S[0][i][0] * aspect;
		S[1][i][0] = S[1][i][0] * aspect;
	}

	/* draw box connecting transformed points. NOTE order and COLORS */
	draw_rect(S[0][0],S[0][1],S[0][2],S[0][3],2,1);

	vdraw_line (S[0][0],S[1][2],8);

	/* sides */
	draw_rect(S[0][0],S[1][0],S[0][1],S[1][1], 4, 0);
	draw_rect(S[0][2],S[1][2],S[0][3],S[1][3], 5, 0);

	draw_rect(S[1][0],S[1][1],S[1][2],S[1][3],3,1);

	/* Draw the "arrow head" */
	for (i= -3;i<4;i++)
		for (j= -3;j<4;j++)
			if (abs(i) + abs(j) < 6)
				plot((int)(S[1][2][0]+i),(int)(S[1][2][1]+j),10);
}



static void draw_rect (V0, V1, V2, V3, color, rect)

VECTOR V0, V1, V2, V3;
int color, rect;

{
VECTOR V[4];
int i;

	for (i=0;i<2;i++) 
	{ /* Since V[2] is not used by vdraw_line don't bother setting it */	
		V[0][i] = V0[i];	
		V[1][i] = V1[i];	
		V[2][i] = V2[i];	
		V[3][i] = V3[i];	
	}	
	if (rect) /* Draw a rectangle */
	{
		for (i=0;i<4;i++)
			if (fabs(V[i][0]-V[(i+1)%4][0]) < -2*bad_check &&
				fabs(V[i][1]-V[(i+1)%4][1]) < -2*bad_check)
					vdraw_line (V[i],V[(i+1)%4],color);
	}
	else /* Draw 2 lines instead */
	{
		for(i=0;i<3;i+=2)
			if (fabs(V[i][0]-V[i+1][0]) < -2*bad_check &&
				fabs(V[i][1]-V[i+1][1]) < -2*bad_check)
					vdraw_line (V[i],V[i+1],color);
	}
	return;
}



/* replacement for plot - builds a table of min and max x's instead of plot */
/* called by draw_line as part of triangle fill routine */
static void _fastcall putminmax(int x,int y,int color)
{
	if(y >= 0 && y < ydots)
	{
		if(x < minmax_x[y].minx) minmax_x[y].minx = x;
		if(x > minmax_x[y].maxx) minmax_x[y].maxx = x;
	}
}

/*
	This routine fills in a triangle. Extreme left and right values for
	each row are calculated by calling the line function for the sides.
	Then rows are filled in with horizontal lines
*/
#define MAXOFFSCREEN  2 /* allow two of three points to be off screen */

static void _fastcall putatriangle(struct point pt1,struct point pt2,
					struct point pt3,int color)
{
	extern struct point p1,p2,p3;
	int miny,maxy;
	int x,y,xlim;

	/* Too many points off the screen? */
	if(offscreen(pt1) + offscreen(pt2) + offscreen(pt3) > MAXOFFSCREEN)
		return;

	p1 = pt1; /* needed by interpcolor */
	p2 = pt2;
	p3 = pt3;

	/* fast way if single point or single line */
	if (p1.y == p2.y && p1.x == p2.x)
	{
		plot = fillplot;
		if (p1.y == p3.y && p1.x == p3.x)
			(*plot)(p1.x, p1.y, color);
		else
			draw_line(p1.x,p1.y,p3.x,p3.y,color);
		plot = normalplot;
		return;
	}
	else if ( (p3.y == p1.y && p3.x == p1.x) || (p3.y == p2.y && p3.x == p2.x) )
	{
		plot = fillplot;
		draw_line(p1.x,p1.y,p2.x,p2.y,color);
		plot = normalplot;
		return;
	}

	/* find min max y */
	miny = maxy = p1.y;
	if(p2.y < miny) miny = p2.y;
	else 		maxy = p2.y;
	if(p3.y < miny) miny = p3.y;
	else if(p3.y > maxy) maxy = p3.y;

	/* only worried about values on screen */
	if(miny < 0)		miny = 0;
	if(maxy >= ydots) maxy = ydots-1;

	for(y=miny;y<=maxy;y++)
	{
		minmax_x[y].minx = (int)INT_MAX;
		minmax_x[y].maxx = (int)INT_MIN;
	}

	/* set plot to "fake" plot function */
	plot = putminmax;

	/* build table of extreme x's of triangle */
	draw_line(p1.x,p1.y,p2.x,p2.y,0);
	draw_line(p2.x,p2.y,p3.x,p3.y,0);
	draw_line(p3.x,p3.y,p1.x,p1.y,0);

	for(y=miny;y<=maxy;y++)
	{
		xlim = minmax_x[y].maxx;
		for(x=minmax_x[y].minx;x<=xlim;x++)
		(*fillplot)(x,y,color);
	}
	plot = normalplot;
}


static int _fastcall offscreen(struct point pt)
{
	if(pt.x >= 0)
		if(pt.x < xdots)
			if(pt.y >= 0)
				if(pt.y < ydots)
					return(0); /* point is ok */
	if (abs(pt.x) > 0-bad_check || abs(pt.y) > 0-bad_check)
		return(99); /* point is bad */
	return(1); /* point is off the screen */
}

static void _fastcall clipcolor(int x,int y,int color)
{
	if(0 <= x	&& x < xdots	&&
		0 <= y	&& y < ydots	&&
		0 <= color && color < filecolors)
	{
		standardplot(x,y,color);

		if (Targa_Out)
			if (!(glassestype==1 || glassestype==2)) /* standardplot modifies color in these types */
				targa_color(x, y, color);
	}
}

/*********************************************************************/
/* This function is the same as clipcolor but checks for color being */
/* in transparent range. Intended to be called only if transparency  */
/* has been enabled.												 */
/*********************************************************************/

static void _fastcall T_clipcolor(int x,int y,int color)
{
	if (0 <= x		&& x < xdots			&& /*  is the point on screen?  */
		0 <= y	&& y < ydots			&& /*  Yes?  */
		0 <= color && color < colors	&& /*  Colors in valid range?  */
		/*  Lets make sure its not a transparent color  */
		(transparent[0] > color || color > transparent[1]))
	{
		standardplot(x,y,color); /* I guess we can plot then  */

		if (Targa_Out)
			if (!(glassestype==1 || glassestype==2)) /* standardplot modifies color in these types */
				targa_color(x, y, color);
	}
}

/************************************************************************/
/* A substitute for plotcolor that interpolates the colors according	*/
/* to the x and y values of three points (p1,p2,p3) which are static in	*/
/* this routine															*/
/*																		*/
/*	In Light source modes, color is light value, not actual color		*/
/*	Real_Color always contains the actual color							*/
/************************************************************************/

static void _fastcall interpcolor(int x,int y,int color)
{
	int D,d1,d2,d3;

  /* this distance formula is not the usual one - but it has the virtue
		that it uses ONLY additions (almost) and it DOES go to zero as the
		points get close.
		*/

	d1 = abs(p1.x-x)+abs(p1.y-y);
	d2 = abs(p2.x-x)+abs(p2.y-y);
	d3 = abs(p3.x-x)+abs(p3.y-y);

	D = (d1 + d2 + d3) << 1;
	if(D)
	{  /* calculate a weighted average of colors -
		long casts prevent integer overflow. This can evaluate to zero */
		color = ((long)(d2+d3)*(long)p1.color +
			(long)(d1+d3)*(long)p2.color +
			(long)(d1+d2)*(long)p3.color) / D;
	}
	
	if(0 <= x		&& x < xdots	&&
		0 <= y		&& y < ydots	&&
		0 <= color && color < colors &&
		(transparent[1] == 0 || Real_Color > transparent[1] ||
		transparent[0] > Real_Color))
	{
		if (Targa_Out)
			if (!(glassestype==1 || glassestype==2)) /* standardplot modifies color in these types */
			    D = targa_color(x, y, color);
 
		if (FILLTYPE >= 5)
			if (Real_V && Targa_Out)
			    color = D;
			else
                        {
                            color =  (1 + (unsigned)color * IAmbient)/256;
                            if (color == 0)
                                color = 1;
                        }
		standardplot(x,y,color);
	}
}



/*
	In non light source modes, both color and Real_Color contain the
	actual pixel color. In light source modes, color contains the
	light value, and Real_Color contains the origninal color

	This routine takes a pixel modifies it for lightshading if appropriate
	and plots it in a Targa file. Used in plot3d.c

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -