3Â÷¿ø ±×·¡ÇÈ ½Ã¿¬ ÇÁ·Î±×·¥°ú 3Â÷¿ø ±×·¡ÇÈ µ¥ÀÌÅÍ »ý¼º ¿¹Á¦

3Â÷¿ø °ø°£¿¡¼­ ÀÓÀÇÀÇ °³¼öÀÇ ¼±À» ÀÔ·Â¹Þ¾Æ ÀÌ°ÍÀ» ¿ø±Ù¹ýÀ¸·Î Æò¸é¿¡ Ç¥½ÃÇØ ÁÖ´Â ÇÁ·Î±×·¥ÀÔ´Ï´Ù. È­»ìÇ¥ Å°·Î ÀÚÀ¯ÀÚÀç·Î 3Â÷¿ø °ø°£À» µå³ªµé¸ç, ¿øÇÏ´Â À§Ä¡¿¡¼­ ¿øÇÏ´Â °¢µµ·Î ¹°Ã¼¸¦ º¼ ¼ö ÀÖ½À´Ï´Ù. Àå¸éÀÇ Å©±â´Â â Å©±â¿¡ ¸Â°Ô ÀÚµ¿À¸·Î Á¶ÀýµË´Ï´Ù. (â Å©±â°¡ Á¤»ç°¢ÇüÀ̾î¾ß È­¸é ºñÀ²ÀÌ ¸Â°Ô ³ª¿É´Ï´Ù)

¸ðµç ¿òÁ÷ÀÓÀº ÇöÀç È­¸éÀ» ±âÁØÀ¸·Î À¯¿¬ÇÏ°Ô ÇàÇØÁý´Ï´Ù. ´Ü, Shift¿Í À§Ä¡ À̵¿ Å°¸¦ ÇÔ²² ´©¸£¸é YÃà °¢µµ°¡ ¹«½ÃµÇ¾î À̵¿ÇÕ´Ï´Ù. (¿¹¸¦ µé¾î ¾Æ·¡¸¦ º¸¸é¼­ ¾ÕÀ¸·Î °¡´Â °ÍÀÌ °¡´ÉÇØÁý´Ï´Ù.)

ƯÈ÷ ÀÌ ÇÁ·Î±×·¥Àº MDI¸¦ ¾²°í À־, ÇÑ ÆÄÀÏÀ» Ç¥½ÃÇϴ âÀ» ¿©·¯ °³ ¸¸µé ¼ö Àֱ⠶§¹®¿¡ ¾Æ·¡Ã³·³ ¸Å¿ì Èï¹Ì·Î¿î È°¿ëµµ ÇÒ ¼ö ÀÖ½À´Ï´Ù. ´Ù¸¥ ¾î¶² ¶óÀ̺귯¸®µµ ¾²Áö ¾Ê°í ÀÚüÀûÀÎ ¼öÇнÄÀ¸·Î ÁÂÇ¥¸¦ °è»êÇÏ°í ±âº» À©µµ¿ì API¸¸ ½á¼­ ±×¸²À» Ãâ·ÂÇϱ⠶§¹®¿¡ ¼Ò½º ÄÚµå´Â À̽ļºÀÌ ÀÖ½À´Ï´Ù.

°£´ÜÇÑ ±âÇÏÇÐ µµÇü, Á¤´Ù¸éü, Åä·¯½º(Æ©ºê), ±¸, 3Â÷¿ø ±×·¡ÇÁ µî ¿©·¯ Àç¹ÌÀÖ´Â ÀÔü±×¸²µéÀÌ ¿¹Á¦·Î °°ÀÌ µé¾îÀÖ½À´Ï´Ù. ÆÄÀÏ Ã¹ ÁÙ¿¡ Ãâ·ÂÇÏ°í ½ÍÀº ¼±ÀÇ °¹¼ö¸¦ ³Ö°í, ±× ´ÙÀ½ ¼±ÀÇ Ã¹ Á¡ÀÇ X Y Z ÁÂÇ¥¿Í ³¡ Á¡ÀÇ X Y Z ÁÂÇ¥¸¦ ³Ö¾î Áֱ⸸ Çϸé ÀÔ·Â µ¥ÀÌÅ͸¦ ¾ó¸¶µçÁö ¸¸µé ¼ö ÀÖ½À´Ï´Ù.

¼Ò½º ÄÚµå, ½ÇÇà ÆÄÀÏ, ¿¹Á¦ ±×·¡ÇÈ µ¥ÀÌÅÍ ¹Þ±â (3ddemo.zip, 172K)

Ȥ½Ã MFC71.DLL°ú MSVCR71.DLLÀÌ ¾ø¾î¼­ ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇÁö ¾ÊÀ¸¸é ÀÌ ¾ÐÃà ÆÄÀϵµ ¹Þ¾Æ¼­ À©µµ¿ì ½Ã½ºÅÛ Æú´õ¿¡ ¼³Ä¡ÇϽñ⠹ٶø´Ï´Ù.

¹öÀü º° º¯È­ »çÇ×

2021³â 1¿ù, shift¸¦ ´©¸¥ »óÅ·δ ¿ìŬ¸¯ µå·¡±×¸¦ Çؼ­ ½ÃÁ¡ º¯È¯ÀÌ µÇÁö ¾Ê´ø ¿À·£ °íÁúÀûÀÎ ¹®Á¦¸¦ ÇØ°áÇß½À´Ï´Ù.

2019³â 9¿ù, ¿¹Á¦ µ¥ÀÌÅÍ¿¡ 3Â÷¿ø ±×·¡ÇÈ ¸ðµ¨ÀÇ °íÀüÀÎ 'À¯Å¸ ÁÖÀüÀÚ'¸¦ Ãß°¡Çß½À´Ï´Ù.

¿À·£¸¸¿¡ ¾÷µ¥ÀÌÆ® µÈ 2018³â 11¿ù 29ÀÏ ¹öÀüÀº,

2005³â 4¿ù 27ÀÏ ¹öÀüÀº,

2004³â 10¿ù 10ÀÏ ¹öÀüÀº (2.2),

2004³â 2¿ù 24 - 3¿ù 1ÀÏ ¹öÀüÀº (2.0),

2003³â 4¿ù 26ÀÏ ¹öÀüÀº,


½ºÅ©¸°¼¦


¿¹Á¦ µ¥ÀÌÅÍ »ý¼º

´ÙÀ½Àº ÀÌ ÇÁ·Î±×·¥À¸·Î º¼ ¼ö ÀÖ´Â 3Â÷¿ø ±×·¡ÇÈ µ¥ÀÌÅ͸¦ »ý¼ºÇØ ÁÖ´Â ÇÁ·Î±×·¥ÀÔ´Ï´Ù.

1. ¹ÝÁö¸§ÀÌ RADIUÀÌ°í, Áß½ÉÀÌ DX, DY, DZÀÎ ±¸.

¿øÀº DELTA¸¸ÇÑ Á¤¹Ðµµ·Î Ç¥ÇöÇÕ´Ï´Ù. °ªÀÌ ÀÛÀ»¼ö·Ï ÃÎÃÎÇØÁý´Ï´Ù. M_PI/15´Â 15°¢ÇüÀ» ÀǹÌÇÏÁö¿ä.

int Build3dSphere()
{
#define M_PI 3.141592
#define RADIU 200

#define DX 0
#define DY 0
#define DZ 0
#define DELTA M_PI/15
	FILE *fp; double a,b;
	fp=fopen("d:\\±¸.txt", "wt");
	for(b=0;b<=2*M_PI;b+=DELTA) {
		for(a=0;a<2*M_PI;a+=DELTA) {
			fprintf(fp, "%f %f %f ", cos(b)*cos(a)*RADIU+DX, sin(b)*cos(a)*RADIU+DY,
				sin(a)*RADIU+DZ);
			fprintf(fp, "%f %f %f\n", cos(b)*cos(a+DELTA)*RADIU+DX, sin(b)*cos(a+DELTA)*RADIU+DY,
				sin(a+DELTA)*RADIU+DZ);

			fprintf(fp, "%f %f %f ", cos(b)*cos(a)*RADIU+DX, cos(b)*sin(a)*RADIU+DY,
				sin(b)*RADIU+DZ);
			fprintf(fp, "%f %f %f\n", cos(b)*cos(a+DELTA)*RADIU+DX, cos(b)*sin(a+DELTA)*RADIU+DY,
				sin(b)*RADIU+DZ);
		}
	}
	fclose(fp);
	return 0;
}

2. ÇÁ·¢Å» ³ª¹«

3Â÷¿ø ±×·¡ÇÈ ½Ã¿¬ ÇÁ·Î±×·¥ÀÇ ¼Ò½º Äڵ忡¼­ ³»ºÎÀûÀ¸·Î ¾²ÀÎ C3dMatrix¿Í C3dPoint Ŭ·¡½º¸¦ ÀÌ¿ëÇÕ´Ï´Ù. »õ °¡ÁöÀÇ À§Ä¡´Â ¿ø·¡ÀÇ °¡ÁöÀÇ ¹æÇâÀ» Çà·Ä·Î º¯È¯ÇÏ¿© ¾ò¾îÁý´Ï´Ù.

void CreateBranch(const C3dMatrix& mat, const C3dPoint& pos, double lengt)
{
	if(lengt<50) return;
	C3dPoint newpos(0, 0, -lengt); newpos=mat*newpos+pos;
	printf("%f %f %f %f %f %f\n", pos.x, pos.y, pos.z, newpos.x, newpos.y, newpos.z);

	//»õ Á¤Á¡¿¡¼­ ¼±ºÐÀ» ¶Ç ¼¼ °³ ¸¸µé¾î È£Ãâ
	C3dMatrix rotY(
		cos(M_PI/8), 0, -sin(M_PI/8),
		0, 1, 0,
		sin(M_PI/8), 0, cos(M_PI/8)
		);
	C3dMatrix rotZ(
		cos(2*M_PI/3), -sin(2*M_PI/3), 0,
		sin(2*M_PI/3), cos(2*M_PI/3), 0,
		0,0,1
		);
	C3dMatrix res=mat*rotY; CreateBranch(res, newpos, lengt*4/5);
	res=mat*rotZ*rotY; CreateBranch(res, newpos, lengt*4/5);
	res=mat*rotZ*rotZ*rotY; CreateBranch(res, newpos, lengt*4/5);
}

À§ÀÇ °æ¿ì, ÇÑ °¡Áö¿¡¼­ ¼¼ °³ÀÇ °¡Áö°¡ ¿ø·¡ °¡Áöº¸´Ù 22.5µµ Á¤µµ ±Á¾îÁø ä 120µµ °£°ÝÀ¸·Î ±ÕÀÏÇÏ°Ô »¸¾î ³ª¿É´Ï´Ù. ±æÀÌ´Â ¿ø·¡ °¡ÁöÀÇ 80%°¡ µÇÁö¿ä. Ãʱ⿡´Â

	C3dMatrix mat(C3dMatrix::identity); C3dPoint pt(0, 0, 100);
	CreateBranch(mat, pt, 200);

ÀÌ·¸°Ô ½ÇÇàÀ» ½ÃÀÛÇØ º¸¼¼¿ä.

3. Æ®·çŸÀÔ ±Û²ÃÀÇ È¹ ÃßÃâ

#define fixtof(p) ( ((double)*((long *)&p))/65536.0 )

int gx, gy;
#define DELTA 0.4
void draw_qspline(POINTFLOAT a, POINTFLOAT b, POINTFLOAT c)
{
	//printf("Draw spline from %g %g - (%g %g) - %g %g\n", a.x,a.y, b.x,b.y, c.x,c.y);
	float p,q,r,t;
	for(t=0.0;t<1.0;t+=DELTA) {
		p=(a.x-2*b.x+c.x)*t*t+(2*b.x-2*a.x)*t+a.x;
		q=(a.y-2*b.y+c.y)*t*t+(2*b.y-2*a.y)*t+a.y;
		printf("0 %g %g ", p+gx,q+gy);

		r=t+DELTA; if(r>1) r=1;
		p=(a.x-2*b.x+c.x)*r*r+(2*b.x-2*a.x)*r+a.x;
		q=(a.y-2*b.y+c.y)*r*r+(2*b.y-2*a.y)*r+a.y;
		printf("0 %g %g\n", p+gx,q+gy);
	}
}

void draw_line(float a, float b,float c,float d)
{
	printf("0 %g %g 0 %g %g\n", a+gx,b+gy, c+gx,d+gy);
}

void MakeDemo(HDC hDC, UINT wr, int mx, int my)
{
	MAT2 mat2={{0,5},{0,0},{0,0},{0,-5}}; GLYPHMETRICS gm; PSTR buf; DWORD dwSize;
	dwSize=::GetGlyphOutline(hDC, wr, GGO_NATIVE, &gm, 0, 0, &mat2);
	buf=new char[dwSize]; gx=mx, gy=my;
	::GetGlyphOutline(hDC, wr, GGO_NATIVE, &gm, dwSize, buf, &mat2);

	//now, render the glyph data
	TTPOLYGONHEADER *ptth; TTPOLYCURVE *ppc; int i,pos=0;
	POINTFLOAT pa={-999,-999},pb,pc, totalbegin, totalend;
	do {
		ppc=(TTPOLYCURVE *)(buf+pos);
		if(ppc->wType!=TT_PRIM_LINE && ppc->wType!=TT_PRIM_QSPLINE) {
			ptth=(TTPOLYGONHEADER *)(buf+pos);
			if(pa.x!=-999)
				draw_line(totalbegin.x, totalbegin.y, totalend.x, totalend.y);
			pa.x=fixtof(ptth->pfxStart.x); pa.y=fixtof(ptth->pfxStart.y);
			totalbegin=pa;
			pos+=sizeof(*ptth); ppc=(TTPOLYCURVE *)(buf+pos);
		}
		switch(ppc->wType) {
		case TT_PRIM_QSPLINE:
			for(i=0;i<ppc->cpfx-1;i++) {
				pb.x=fixtof(ppc->apfx[i].x); pb.y=fixtof(ppc->apfx[i].y);
				if(i<ppc->cpfx-2) {
					pc.x=(pb.x+fixtof(ppc->apfx[i+1].x))/2;
					pc.y=(pb.y+fixtof(ppc->apfx[i+1].y))/2;
				} else {
					pc.x=fixtof(ppc->apfx[i+1].x);
					pc.y=fixtof(ppc->apfx[i+1].y);
				}
				draw_qspline(pa,pb,pc);
				pa=pc; totalend=pa;
			}
			break;
		case TT_PRIM_LINE:
			for(i=0;i<ppc->cpfx;i++) {
				pb.x=fixtof(ppc->apfx[i].x);; pb.y=fixtof(ppc->apfx[i].y);
				draw_line(pa.x,pa.y, pb.x,pb.y);
				pa=pb;
			}
			totalend=pa;
		}
		pos+=sizeof(*ppc)+sizeof(POINTFX)*(ppc->cpfx-1);
	}
	while(pos<dwSize);
	if(pa.x!=-999) draw_line(totalbegin.x,totalbegin.y, totalend.x,totalend.y);
	delete []buf;
}

¿øÇÏ´Â ±Û²Ã ¿ÀºêÁ§Æ®°¡ ¼³Á¤µÇ¾î ÀÖ´Â HDC ÇÚµé°ú, ¸¸µé°í ½ÍÀº ±ÛÀÚÀÇ À¯´ÏÄÚµå ¹øÈ£¸¦ wr¿¡ ÁöÁ¤ÇÏ¿© MakeDemo ÇÔ¼ö¸¦ È£ÃâÇÏ¸é µË´Ï´Ù.

4. º£Áö¾î °î¼±°ú °î¸é

void CCubicBezierCurveOn3D(double t, const C3dPoint *ctrlpt, C3dPoint& o)
{
	double _t = 1 - t;
	double coef[4] = {
		_t * _t * _t,
		3 * t * _t * _t,
		3 * t * t * _t,
		t * t * t
	};
	for (int q = 0; q < 3; q++) {
		double C3dPoint::* mptr = (q == 0 ? &C3dPoint::x : q == 1 ? &C3dPoint::y : &C3dPoint::z);
		o.*mptr = ctrlpt[0].*mptr * coef[0] + ctrlpt[1].*mptr * coef[1] + ctrlpt[2].*mptr * coef[2] + ctrlpt[3].*mptr * coef[3];
	}
}

void CCubicBezierPlaneOn3D(double ty, double tx, const C3dPoint (*ctrlpt)[4], C3dPoint& o)
{
	double _ty = 1 - ty, _tx = 1 - tx;
	double C_y[4] = {
		_ty * _ty * _ty,
		3 * ty * _ty * _ty,
		3 * ty * ty * _ty,
		ty * ty * ty
	};
	double C_x[4] = {
		_tx * _tx * _tx,
		3 * tx * _tx * _tx,
		3 * tx * tx * _tx,
		tx * tx * tx
	};
	for (int q = 0; q < 3; q++) {
		double C3dPoint::* mptr = (q == 0 ? &C3dPoint::x : q == 1 ? &C3dPoint::y : &C3dPoint::z);
		o.*mptr = 0;
		for (int y = 0; y < 4; y++)
			o.*mptr += ctrlpt[y][0].*mptr * C_y[y] * C_x[0] + ctrlpt[y][1].*mptr * C_y[y] * C_x[1] +
				ctrlpt[y][2].*mptr * C_y[y] * C_x[2] + ctrlpt[y][3].*mptr * C_y[y] * C_x[3];
	}
}

°î¼± ¹öÀüÀº Á¦¾îÁ¡ 4°³ÀÇ ¹è¿­À» ctrlpt¿¡ ³Ö°í 0 ÀÌ»ó 1 ÀÌÇÏÀÇ ¸Å°³º¯¼ö t¸¦ ÁÖ¸é ±× ÁöÁ¡¿¡ ÇØ´çÇÏ´Â ±ËÀû o¸¦ ¾òÀ» ¼ö ÀÖ½À´Ï´Ù.

°î¸é ¹öÀüÀº Á¦¾îÁ¡ 4°³·Î ÀÌ·ïÁø º£Áö¾î °î¼± ÀÚü¸¦ 4°³ ¹Þ½À´Ï´Ù. À̸¦ ÁÖ°í ¸Å°³º¯¼öµµ yÃà°ú xÃà 2°³¸¦ ÁÖ¸é ±× ÁöÁ¡¿¡ ÇØ´çÇÏ´Â ±ËÀû o¸¦ ¾òÀ» ¼ö ÀÖ½À´Ï´Ù.