已有数据存于x[],y[],z[]三个数组,如何用vc编程在屏幕上绘出三维图形?
已有数据存于x[],y[],z[]三个数组,如何用vc编程在屏幕上绘出三维图形,不需要讲如何投影等原理,只需提供vc源码(非opengl)。感谢在先,奉上100分。
[解决办法]
伪码:
//in deed you must need normal transition to change
//but i did not know!!
while(some express){
pos_x_projected[index]=x[index]/z[index];
pos_y_projected[index]=y[inedx]/z[index];
index++;
}
//world Cartesian coordinate and viewport to windows in Windows coordinate
//i give you some formula,some stupid don 't understand
(w_pos_x-WINDOWS_CDC_LEFT)/(WINDOWS_CDC_RIGHT-WINDOWS_CDC_LEFT)=(pos_x_projected-VIEWPORT_LEFT)/(VIEWPORT_RIGHT-VIEWPORT_LEFT);
(w_pos_y-WINDOWS_CDC_TOP)/(WINDOWS_CDC_BOTTOM-WINDOWS_CDC_TOP)=(pos_x_projected-VIEWPORT_BOTTOM)/(VIEWPORT_TOP-VIEWPORT_BOTTOM);
//compute the w_pos_x and w_pos_y
//but i don 't where 's viewport in camera ???!!1
//get DC of windows
while(some express){
dc.LineTo(w_pos_x[index],w_pos_y[index])
//some other process to draw a whole primary
}
因为图元的初始位置我们不知道,也不知道摄影机在那,更不知道是否要裁剪,所以这个流水线很难不出错误!!只能当它(x[],y[],x[])都在已经变换好的位置了,但是在实际情况中是不太可能存在的!!!以后请不要激将法,这样在CSDN是没法立足的!
[解决办法]
我有类似代码,关键是要将3维变为屏幕2维坐标,列举几例,不用OpenGl等东西.
realP[3]为你的原始3维数据点坐标,scrP为2维的屏幕坐标,生成2维点后,你Lineto不就行了?但我这个程序未实现任意角度的转换,至于还要穿插缩放与偏移算法,这里恕不展示了.
switch(ViewType)
{
case VIEWTYPE_FUS://俯视图
scrP->x = realP[0];
scrP->y = realP[1];
break;
case VIEWTYPE_ZHS://正视图
scrP->x = realP[0];
scrP->y = realP[2];
break;
case VIEWTYPE_YOS://右视图
scrP->x = realP[1];
scrP->y = realP[2];
break;
case VIEWTYPE_ZD0://西南正等轴测图
scrP->x = (realP[0]-realP[1])*COS_30;
scrP->y = (realP[0]+realP[1])*SIN_30+realP[2];
break;
case VIEWTYPE_ZD1://东南正等轴测图
scrP->x = (realP[0]+realP[1])*COS_30;
scrP->y = (realP[1]-realP[0])*SIN_30+realP[2];
break;
......
default:
scrP->x = 0;
scrP->y = 0;
break;
}
[解决办法]
#include <cmath>void CD3DrawDlg::Draw3D(){ const COLORREF CR_NULL = RGB(0,0,0); //无点处是黑色 const COLORREF CR_POINT = RGB(0,0,255); //有点处是蓝色 const int MAXRANGE = 10; //测试数组的大小 const int NULLDIA = 3; //没有数据点的直径 const int POINTDIA = 8; //有数据点的直径 const int POINTDST = 20; //点的距离 const int AXISLENGTH = 200; //x,y,z轴长 //这个是Z = 1平面上的 X = Y 的曲线 int xdata[MAXRANGE] = {1,2,3,4,5,6,7,8,9,10}; int ydata[MAXRANGE] = {1,2,3,4,5,6,7,8,9,10}; int zdata[MAXRANGE] = {1,1,1,1,1,1,1,1,1,1}; CRect rt; GetClientRect(rt); CClientDC dc(this); int X0 = rt.Width()/2; int Y0 = rt.Height()/2; dc.TextOut(X0 - 35,Y0 - 20,"(0,0)");//画原点 dc.MoveTo(X0,Y0); //画X轴 dc.LineTo(X0 + AXISLENGTH,Y0); dc.TextOut(X0 + AXISLENGTH + 10,Y0 - 20,"X轴"); dc.MoveTo(X0,Y0); //画Y轴 dc.LineTo(X0 - int(AXISLENGTH*sqrt(0.5)),Y0 + 141); dc.TextOut(X0 - int(AXISLENGTH*sqrt(0.5)) - 35,Y0 + 141,"Y轴"); dc.MoveTo(X0,Y0); //画Z轴 dc.LineTo(X0,Y0 - AXISLENGTH); dc.TextOut(X0 - 35,Y0 - AXISLENGTH - 20,"Z轴"); //画出所有坐标点 int x,y,z; CBrush br(CR_NULL); CPen pen(PS_SOLID,1,CR_NULL); dc.SelectObject(&br); dc.SelectObject(&pen); for (x=0;x<MAXRANGE;++x)//这个操作可以省去不画,画面会简洁一些 { for (y=0;y<MAXRANGE;++y) { for (z=0;z<MAXRANGE;++z) { dc.Ellipse( X0 + x*POINTDST - int(sqrt(0.5)*POINTDST*y), Y0 - z*POINTDST + int(sqrt(0.5)*POINTDST*y), X0 + x*POINTDST - int(sqrt(0.5)*POINTDST*y) + NULLDIA, Y0 - z*POINTDST + int(sqrt(0.5)*POINTDST*y) + NULLDIA); } } } //画数组里的点 CPen penPt(PS_SOLID,1,CR_POINT); CBrush brPt(CR_POINT); dc.SelectObject(&penPt); dc.SelectObject(&brPt); int i=0; for (i=0;i<MAXRANGE;++i) { dc.Ellipse( X0 + xdata[i]*POINTDST - int(sqrt(0.5)*POINTDST*ydata[i]), Y0 - zdata[i]*POINTDST + int(sqrt(0.5)*POINTDST*ydata[i]), X0 + xdata[i]*POINTDST - int(sqrt(0.5)*POINTDST*ydata[i]) + POINTDIA, Y0 - zdata[i]*POINTDST + int(sqrt(0.5)*POINTDST*ydata[i]) + POINTDIA); }}