网页新闻贴吧知道音乐图片视频地图文库
进入贴吧全吧搜索吧内搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
04月24日漏签0天
easyx吧 关注:8,121贴子:40,371
  • 看贴

  • 图片

  • 精品

  • 游戏

  • 14回复贴,共1页
<<返回easyx吧
>0< 加载中...

一个有贴图3D的长方体

  • 只看楼主
  • 收藏

  • 回复
  • 白芦花
  • 三年级
    6
已加了z轴消隐


上面是效果


  • 广州硕数
勒索病毒解密,上门服务,最快一小时完成
2018-04-24 16:38 广告
  • 白芦花
  • 三年级
    6
两个资源



第一部分:
//一个有贴图3D的长方体
//鼠标左键旋转 右键平移,滑轮缩放
//加了z轴消隐
#include "graphics.h"
#include <time.h>
#include <math.h>
#include <conio.h>
#include <stdio.h>
#definePI3.1415926536
#define byte unsigned char


int width;//工作区宽
int height;//工作区高
int cent_x,cent_y;//当前位置


IMAGE workmap;//画图空间
double * zmap2d;//屏幕点--z轴比较


char *imgname0="绿鱼.jpg";//长方体的四面:长方形
char *imgname1="红鱼.jpg";//长方体的二面:正方形 高=长方形的宽
int jpgw,jpgh;




double viewZ = 3;// 视点 z 轴坐标


// 定义三维点
struct POINT3D
{
double x;
double y;
double z;
byte r;
byte g;
byte b;
byte a;
COLORREF color;//先计算好颜色
};
struct PointCloud //点云
{
long num; //个数
struct POINT3D * p;//点坐标和颜色
};


struct PointCloud *dianyun0; //点云
struct POINT3D * p3;//指向点云中的点


//声明类,函数————————————————————
struct PointCloud *img2PointC(char *imgname);
void cube_img();


void error(char *s)
{
printf("%s\n",s);
getch();
exit(1);
}


void ZoomImage(IMAGE* P,double ZoomRate)
{//目标图像,水平缩放比,是否高质量算法,垂直缩放比
//不填写垂直缩放参数则默认和水平相等
IMAGE tmp;
IMAGE * Q=&tmp;
tmp=*P;//复制原图像,


int Qwidth=Q->getwidth();
int Qheight=Q->getheight();


//根据缩放比率设定目标图像大小
P->Resize((int)(Qwidth*ZoomRate),(int)(Qheight*ZoomRate));
int Pwidth=P->getwidth();
int Pheight=P->getheight();


//分别对原图像和目标图像获取指针
DWORD* M=GetImageBuffer(P);
DWORD* N=GetImageBuffer(Q);
//选择低质量则按常规方法缩放
{
for(int i=0;i<Pheight;i++)
for(int j=0;j<Pwidth;j++)
//根据目标图像像素点位置逆推算原图像像素点赋值
M[j+i*Pwidth]=N[(int)(j/ZoomRate)+(int)(i/ZoomRate)*Qwidth];
}
}


  • 白芦花
  • 三年级
    6
第二部分:
void rotate(float rx,float ry,float rz)
{
p3=dianyun0->p;
double x,y;
double anglex,angley,anglez;
double cosanglex,sinanglex,sin_anglex;
double cosangley,sinangley,sin_angley;
double cosanglez,sinanglez,sin_anglez;
double pi180=PI/180;
anglex= pi180*rx;
cosanglex=cos(anglex);sinanglex=sin(anglex);sin_anglex=sin(-anglex);
angley= pi180*ry;
cosangley=cos(angley);sinangley=sin(angley);sin_angley=sin(-angley);
anglez= pi180*rz;
cosanglez=cos(anglez);sinanglez=sin(anglez);sin_anglez=sin(-anglez);


for(int i=0; i<dianyun0->num; i++)
{
// 使该点围绕三个坐标轴做旋转运动
//为了速度快三个旋转函数内嵌这里
//RotateX(p3, anglex);//
y = p3->y;
p3->y = p3->y * cosanglex + p3->z * sin_anglex;
p3->z = y * sinanglex + p3->z * cosanglex;
//RotateY(p3, angley);//180
x = p3->x;
p3->x = p3->x * cosangley + p3->z * sin_angley;
p3->z = x * sinangley + p3->z * cosangley;
//RotateZ(p3, anglez);//180
x = p3->x;
p3->x = p3->x * cosanglez + p3->y * sin_anglez;
p3->y = x * sinanglez + p3->y * cosanglez;


p3++;


}
}


void huapin()//绘到屏幕
{
//POINT p2d;
int x,y;//p2d.x,p2d.y
long p2;


//清空图形————————————————————
//cleardevice();// 清除屏幕
SetWorkingImage(&workmap);// 设置绘图目标为 img 对象
//这个函数用于清空矩形区域
clearrectangle(0,0,width,height);
SetWorkingImage();// 设置绘图目标为绘图窗口
//————————————————————————


//清空比较器
memset(zmap2d,0,sizeof(double)*width*height);


p3=dianyun0->p;
DWORD* m_pMem = GetImageBuffer(&workmap);

double tmp;
for(int i=0; i<dianyun0->num; i++)
{
// 投影该点到屏幕上
//p2d = Projection(p3);
tmp=1;//( viewZ / (viewZ - p3->z) ) ;
x = (int)(p3->x * tmp + 0.5) + cent_x;//width/2;
y = (int)(p3->y * tmp + 0.5) + cent_y;//height/2;
//return p2d;


// 画点
if(!(x<0 || y<0 || x>=width || y>=height))
{
//m_pMem[y*width+x]=p3->color; //已经计算好 ,加快一点速度RGB(p3->r,p3->g,p3->b);

p2=y*width+x;
if(m_pMem[p2]==0)
{
m_pMem[p2]=p3->color; //
zmap2d[p2]=p3->z;//z坐标
}
else
{
if(zmap2d[p2]>p3->z)
{
m_pMem[p2]=p3->color; //
zmap2d[p2]=p3->z;//z坐标


}
//else{不用保存};


}
}
p3++;

}

// 复制到屏幕
putimage(0,0,&workmap,SRCCOPY);
FlushBatchDraw();
}


  • 白芦花
  • 三年级
    6
第三部分:
struct POINT3D operator*(struct POINT3D a,float b){
struct POINT3D c;
c.x=a.x*b;
c.y=a.y*b;
c.z=a.z*b;
c.color=a.color;
c.r=a.r;
c.g=a.g;
c.b=a.b;
c.a=a.a;
return c;
}


void size3p(float f)//缩放
{
p3=dianyun0->p;
for(int i=0; i<dianyun0->num; i++)
{
*p3=*p3*f;
p3++;
}
}




voidinityiqie()//一些全局数据的初始化
{
width= GetSystemMetrics(SM_CXFULLSCREEN); //屏幕宽
height= GetSystemMetrics(SM_CYFULLSCREEN); //屏幕高
cube_img ();


Resize(&workmap,int(width),int(height));
//z轴比较器分配空间
zmap2d=(double *)malloc(sizeof(double)*width*height);
}


  • 白芦花
  • 三年级
    6
第四部分:
void main()
{
inityiqie();//一些全局数据的初始化
MOUSEMSG m;//鼠标消息
int r_button_down=0,l_button_down=0;//鼠标左右键是否按下
int last_x=0,last_y=0;//上一次位置
//int cent_x,cent_y;//当前位置
cent_x=width/2;cent_y=height/2;
initgraph(width,height);//640, 480
BeginBatchDraw();
huapin();//绘到屏幕


while(1)
{
m=GetMouseMsg(); //获取鼠标消息
switch(m.uMsg)
{
case WM_MOUSEMOVE://鼠标移动消息
if(r_button_down)//右键按下并移动
{
//先用这个假平移,(在屏幕上平移,3D坐标不变)
cent_x+=(m.x-last_x);//当前位置 = 鼠标位置 - 上一次位置
cent_y+=(m.y-last_y);
//pingyi(cent_x,cent_y);//拖动 平移
huapin();//绘到屏幕
}
if(l_button_down)//左键按下并移动
{
rotate((m.y-last_y)/-2,(m.y-last_y)/2,m.x-last_x);//旋转
huapin();//绘到屏幕
}
last_x=m.x;//上一次位置
last_y=m.y;
break;
case WM_RBUTTONDOWN://右键按下
r_button_down=1;
l_button_down=0;
break;
case WM_RBUTTONUP://右键抬起
r_button_down=0;
//last_x=m.x;
//last_y=m.y;
break;
case WM_LBUTTONDOWN://左键按下
l_button_down=1;
break;
case WM_LBUTTONUP://左键抬起
l_button_down=0;
break;
case WM_MOUSEWHEEL://滑轮缩放
l_button_down=0;
if(m.wheel>0)
size3p(1.01);//放大
else
size3p(0.99);//缩小
huapin();//绘到屏幕
default:break;
}
}
EndBatchDraw();
closegraph();
}


  • 白芦花
  • 三年级
    6
第五部分:
//图像转换为3D点云
struct PointCloud *img2PointC (char *imgname)
{
IMAGE jpg;
int zoom=2;
loadimage(&jpg,imgname);
ZoomImage(&jpg,zoom);
//double size;
//size=500.0/jpg.getwidth();
//ZoomImage(&jpg,size,false);
//为点云分配空间
int w=jpg.getwidth();
int h=jpg.getheight();
jpgw=w;
jpgh=h;
struct PointCloud * ply1;
ply1=(struct PointCloud *)malloc(sizeof(struct PointCloud));
struct PointCloud ply0;

ply0.num=h*w;
ply0.p= (struct POINT3D *)malloc(sizeof(struct POINT3D)*ply0.num);//new


//读入点云
struct POINT3D p1;//暂存一点数据
struct POINT3D * P3d=ply0.p;
DWORD * me=GetImageBuffer(&jpg);
int y,x;
long i=0;
for (y=0;y<h;y++){
for (x=0;x<w;x++){

p1.x= x;//
p1.y= y;
p1.z=0.00;
p1.color=me[x+y*w];//先计算好颜色值交换颜色的红色和蓝色部分
p1.r=GetRValue(p1.color);
p1.g=GetGValue(p1.color);
p1.b=GetBValue(p1.color);
//if(p1.r<250 && p1.g<250 && p1.b<250)//去掉白边
//{
////直接操作显存时,可以通过 BGR 宏交换颜色的红色和蓝色部分。
memcpy(P3d,&p1, sizeof(struct POINT3D));
P3d++;i++;
//}
}




}
ply0.num=i;
memcpy(ply1,&ply0, sizeof(struct PointCloud));
return ply1;


}
//平移
void py(double x,double y,double z){
int j;
p3=dianyun0->p;
for (j=0;j<dianyun0->num;j++){

p3->x+=x;
p3->y+=y;
p3->z+=z;
p3++;

}


}


// 使三维点云按 x 轴旋转指定角度
void rotaterx(double rx)
{
p3=dianyun0->p;
double y;
double anglex= rx;//PI/180*
double cosanglex=cos(anglex);
double sinanglex=sin(anglex);
double sin_anglex=sin(-anglex);
int i;
for(i=0; i<dianyun0->num; i++)
{
// 使该点围绕三个坐标轴做旋转运动
//为了显示速度快一点三个旋转函数内嵌这里
//RotateX(p3, PI*rx/180);//
y = p3->y;
p3->y = p3->y * cosanglex + p3->z * sin_anglex;
p3->z = y * sinanglex + p3->z * cosanglex;


p3++;


}
}


// 使三维点按 y 轴旋转指定角度
void rotatery(double ry)
{
p3=dianyun0->p;
double x;
double angle= ry;//PI/180*
double cosangle=cos(angle);
double sinangle=sin(angle);
double sin_angle=sin(-angle);
int i;
for(i=0; i<dianyun0->num; i++)
{
// 使该点围绕三个坐标轴做旋转运动
//为了显示速度快一点三个旋转函数内嵌这里
//RotateY(struct POINT3D * p, double angle)
x = p3->x;
p3->x = x * cosangle + p3->z * sin_angle;
p3->z = x * sinangle + p3->z * cosangle;
p3++;
}
}


//加上一个面
void aface(struct PointCloud * tmp)
{
struct PointCloud ply1;
long num;
int jia=1;
if (dianyun0==NULL){
dianyun0= (struct PointCloud *)malloc(sizeof(struct PointCloud));
dianyun0->num=0;
dianyun0->p=NULL;
num=0;
jia=0;
}
else{
num=dianyun0->num;
//暂存
ply1.num=dianyun0->num;//memcpy(&ply1,&dianyun0, sizeof(struct PointCloud));
ply1.p=dianyun0->p;
}
num+=tmp->num;//加上一个面


//为点云分配空间
dianyun0->p= (struct POINT3D *)malloc(sizeof(struct POINT3D)*num);//new
p3=dianyun0->p;
if(jia==1){
memcpy(p3,ply1.p, sizeof(struct POINT3D)*ply1.num);p3+=ply1.num;//暂存放回
free(ply1.p);//删除暂存
}
memcpy(p3,tmp->p, sizeof(struct POINT3D)*tmp->num);//加上当前这个面
dianyun0->num = num;
}


//为正方形贴图
void cube_img()
{


struct PointCloud *tmp;
tmp=img2PointC(imgname0);//装入ply点云


//long num=0;//总点的计数
//为点云分配空间
int w=jpgw;
int h=jpgh;
////正方形==========================
//int cube[]={//底面
//{0,0,0;1,0,0;1,1,0;0,1,0},
////顶面
//{0,0,1;1,0,1;1,1,1;0,1,1},
//
////前面
//{0,0,0;1,0,0;1,0,1;0,0,1},
////后面
//{0,1,0;1,1,0;1,1,1;0,1,1},
//
////左面
//{0,0,0;0,1,0;0,1,1;0,0,1},
////右面
//{1,0,0;1,1,0;1,1,1;1,0,1}};
////=================================
//1 底面
aface( tmp);


//平移
py(0,0,-h);
//顶面
aface( tmp);
//返回平移
py(0,0,h);




// 使三维点云按 x 轴旋转指定角度
rotaterx(-PI/180*90);
//前面
aface( tmp);
//平移
py(0,0,h);
//后面
aface( tmp);
rotatery(-PI/180*90);
//
//左右面
free(tmp->p);
free(tmp);
tmp=img2PointC(imgname1);//装入ply点云
aface( tmp);
////平移
py(0,0,w);
aface( tmp);
//py(w/2,h/2,h/2);
rotate(30,30,30);
}


  • KrissiZH
  • 小吧主
    8
好厉害~~~仰慕中。。。。


  • stophin
  • 四年级
    7
厉害厉害


登录百度帐号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 14回复贴,共1页
<<返回easyx吧
分享到:
©2018 Baidu贴吧协议|吧主制度|意见反馈|网络谣言警示