📄 sphereview.cpp
字号:
// sphereView.cpp : implementation of the CSphereView class
//
#include "stdafx.h"
#include "sphere.h"
#include "sphereDoc.h"
#include "sphereView.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
pRGB ForeColor={230,60,90};
///////////////////////////////////////////////////////////////////
//
void CSphereView::lineany(int xa,int ya,int xb,int yb)
{
// int i;
int x,y,xEnd,yEnd;
if(xa==xb){
if(ya==yb)m_pDC->SetPixel(xa,ya,m_ForeColor);
else if (ya<yb){yEnd=yb;y=ya;}
else{yEnd=ya;y=yb;}
while(y<=yEnd)m_pDC->SetPixel(xa,y++,m_ForeColor);
return ;
}//if1
if(ya==yb){
if(xa<=xb){xEnd=xb;x=xa;}
else{xEnd=xa;x=xb;}
while(x<=xEnd)m_pDC->SetPixel(x++,ya,m_ForeColor);
return ;
}//if2
float dx,dy;
dx=(float)abs(xa-xb);
dy=(float)abs(ya-yb);
int k;
if(ya>yb&&xa>xb||ya<yb&&xa<xb)k=1;
else k=0; //tell m>0 or m<0
float p=2*dy-dx;
float twoDy=2*dy,twoDyDx=2*(dy-dx);
if(dx>=dy){
if(xa>xb){x=xb;y=yb;xEnd=xa;}//if3..
else{x=xa;y=ya;xEnd=xb;}//else3..
m_pDC->SetPixel(x,y,m_ForeColor);
if(k)//if4...
while(x<xEnd){
x++;
if(p<0)p+=twoDy;
else{y++;p+=twoDyDx;}
m_pDC->SetPixel(x,y,m_ForeColor);
}//while
else {
// p=-2*dy+dx;
//twoDyDx=2*(-dy+dx);
// dy=-dy;
while(x<xEnd){x++;
if(p>=0)p-=twoDy;
else {y--;p-=twoDyDx;}
m_pDC->SetPixel(x,y,m_ForeColor);
}//while..
}//else4...
}//if3
else {
p=2*dx-dy;
twoDy=2*dx;
twoDyDx=2*(dx-dy);
if(ya>yb){y=yb;x=xb;yEnd=ya;}//if3..
else{y=ya;x=xa;yEnd=yb;}//else3..
if(k)//if5...
while(y<yEnd){y++;
if(p<0)p+=twoDy;
else{x++;p+=twoDyDx;}
m_pDC->SetPixel(x,y,m_ForeColor);
}//while..
else{
p=-2*dx+dy;
twoDy=2*dx;
twoDyDx=2*(dx-dy);
while(y<yEnd){y++;
if(p>=0)p-=twoDy;
else {x--;p-=twoDyDx;}
m_pDC->SetPixel(x,y,m_ForeColor);
}//while..
}//else5...
}//else3
/**/
return ;
}//::lineany()
void CSphereView::lineany(Fpoint p1, Fpoint p2)
{
lineany(p1.x,p1.y,p2.x,p2.y);
}
//oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
double Rvw;
int dengfen=12;
int R=100;
double kd=0.8,ks=0.5,ns=20;
int Il=200;
bool m_bWangge=false,m_bFanshe=false,m_bGuangzhao=false,m_bJingmian=false;
dcpt3 viewpoint={0.0,0.0,0.0}; //视点
dcpt3 lightpoint={500,500,500};
dcpt3 wordpoint={0.0,0.0,0.0}; //球心
dcpt3 U={0.0,1.0,0.0}; //默认以yoz坐标面为观察面
dcpt3 V={0.0,0.0,1.0};
dcpt3 N={1.0,0.0,0.0};
dcpt3 *vw;//向量从viewpoint指向wordpoint
ZP *zp;
Fpoint *ps,*pn,*qs,*qn;
Fpoint miniface[4],_miniface[4];
double danweihua(dcpt3 &a){
double r=sqrt((a.x*a.x)+(a.y*a.y)+(a.z*a.z));
a.x=a.x/r; a.y=a.y/r; a.z=a.z/r;
return r;
}//danweihua()
///////////////////////////////////////////////////////
//建立模型坐标
bool jianmo(){
int i,j;
const int m=dengfen/4;
double th=2.00*PI/dengfen;
zp=new ZP[m+1];
if(!zp) { AfxMessageBox("zp内存分配失败!",MB_OK,0); return false;}//if false
for(i=0;i<m;i++){
zp[i].r=R*cos((double)i*th);
zp[i].z=int(R*sin((double)i*th));
zp[i].pxy=new Fpoint[dengfen+1];
zp[i].fn=new dcpt3[dengfen+1];
zp[i].pn=new dcpt3[dengfen+1];
if(!(zp[i].pxy&&zp[i].fn&&zp[i].pn)) {
AfxMessageBox("内存分配失败!",MB_OK,0);
return false;
}//if new fail
for(j=0;j<dengfen;j++){
zp[i].pxy[j].x=long(zp[i].r*cos(double(j*th)));
zp[i].pxy[j].y=long(zp[i].r*sin(double(j*th)));
if(i==0){
zp[0].pn[j].x=zp[0].pxy[j].x; zp[0].pn[j].y=zp[0].pxy[j].y; zp[0].pn[j].z=0;
danweihua(zp[0].pn[j]);
zp[0].fn[j].x=0; zp[0].fn[j].y=0; zp[0].fn[j].z=0;
}//if(i==0)
else {
zp[i].fn[j].x=-(zp[i-1].z-zp[i].z)*(zp[i-1].pxy[j+1].y-zp[i-1].pxy[j].y);
zp[i].fn[j].y= (zp[i-1].z-zp[i].z)*(zp[i-1].pxy[j+1].x-zp[i-1].pxy[j].x);
zp[i].fn[j].z= ((zp[i-1].pxy[j].x-zp[i].pxy[j].x)*(zp[i-1].pxy[j+1].y-zp[i-1].pxy[j].y)-(zp[i-1].pxy[j].y-zp[i].pxy[j].y)*(zp[i-1].pxy[j+1].x-zp[i-1].pxy[j].x));
danweihua(zp[i].fn[j]);
}//else
/**/ zp[i].pxy[j].c.R=30; zp[i].pxy[j].c.G=100; zp[i].pxy[j].c.B=200;
}//for..
if(i==0){ zp[0].pn[dengfen].x=zp[0].pn[0].x; zp[0].pn[dengfen].y=zp[0].pn[0].y; zp[0].pn[dengfen].z=zp[0].pn[0].z;}
zp[i].fn[dengfen].x=zp[i].fn[0].x; zp[i].fn[dengfen].y=zp[i].fn[0].y; zp[i].fn[dengfen].z=zp[i].fn[0].z;
zp[i].pxy[dengfen].x=zp[i].pxy[0].x; zp[i].pxy[dengfen].y=zp[i].pxy[0].y;
zp[i].pxy[dengfen].c.R=0; zp[i].pxy[dengfen].c.G=0; zp[i].pxy[dengfen].c.B=0;
}//for
zp[m].z=100;
zp[m].r=0;
zp[m].pxy=new Fpoint;
zp[m].pn=new dcpt3;
zp[m].fn=new dcpt3[dengfen+1];
if(!(zp[m].pxy&&zp[m].fn&&zp[m].pn)){AfxMessageBox("内存分配失败!",MB_OK,0); return false;}
zp[m].pxy->x=0; zp[m].pxy->y=0;
zp[m].pn-> x=0; zp[m].pn-> y=0; zp[m].pn->z=1;
for(j=0;j<dengfen;j++){ //计算向量 zp[m].fn[j]
zp[m].fn[j].x=-(zp[m-1].z-zp[m].z)*(zp[m-1].pxy[j+1].y-zp[m-1].pxy[j].y);
zp[m].fn[j].y= (zp[m-1].z-zp[m].z)*(zp[m-1].pxy[j+1].x-zp[m-1].pxy[j].x);
zp[m].fn[j].z=((zp[m-1].pxy[j].x-zp[m].pxy[0].x)*(zp[m-1].pxy[j+1].y-zp[m-1].pxy[j].y)-(zp[m-1].pxy[j].y-zp[m].pxy[0].y)*(zp[m-1].pxy[j+1].x-zp[m-1].pxy[j].x));
danweihua(zp[m].fn[j]);
} zp[m].fn[dengfen].x=zp[m].fn[0].x; zp[m].fn[dengfen].y=zp[m].fn[0].y; zp[m].fn[dengfen].z=zp[m].fn[0].z;
/**/
for(i=1;i<m;i++){ //计算向量 zp[i].pn[j]
for(j=1;j<=dengfen;j++){
zp[i].pn[j].x=zp[i].fn[j].x+zp[i+1].fn[j].x+zp[i+1].fn[j-1].x+zp[i].fn[j-1].x;
zp[i].pn[j].y=zp[i].fn[j].y+zp[i+1].fn[j].y+zp[i+1].fn[j-1].y+zp[i].fn[j-1].y;
zp[i].pn[j].z=zp[i].fn[j].z+zp[i+1].fn[j].z+zp[i+1].fn[j-1].z+zp[i].fn[j-1].z;
danweihua(zp[i].pn[j]);
}//for_j_...
zp[i].pn[0].x=zp[i].pn[dengfen].x; zp[i].pn[0].y=zp[i].pn[dengfen].y; zp[i].pn[0].z=zp[i].pn[dengfen].z;
}//for_i_
/**/
return true;
}//jianmo
/**/
//////////////////////////////////////////////////////
//设置观察坐标系
bool setUVN(dcpt3 wordpoint,dcpt3 viewpoint){
if((wordpoint.x==viewpoint.x)&&(wordpoint.y==viewpoint.y)&&(wordpoint.z==viewpoint.z))
{ AfxMessageBox("球心与视点重合!",MB_OK,0);return true;}
vw=new dcpt3;
if(!vw){AfxMessageBox("vw内存分配失败!",MB_OK,0);
return false;}//if new vw fail
double r;
vw->x=viewpoint.x-wordpoint.x;
vw->y=viewpoint.y-wordpoint.y;
vw->z=viewpoint.z-wordpoint.z;
Rvw=sqrt((vw->x*vw->x)+(vw->y*vw->y)+(vw->z*vw->z));
N.x=-(vw->x)/Rvw; N.y=-(vw->y)/Rvw; N.z=-(vw->z)/Rvw;
r=sqrt((vw->y*vw->y)+(vw->z*vw->z))/Rvw;
U.x=0; U.y=-N.z/r; U.z=N.y/r;
V.x=N.y*U.z-N.z*U.y;
V.y=N.z*U.x-N.x*U.z;
V.z=N.x*U.y-N.y*U.x;
return true;
}//setUVN()
//////////////////////////////////////////////////////
//从世界坐标系转变为视图坐标系
Fpoint w_v(int i,int j){
Fpoint pot;
pot.x=int((U.x*zp[i].pxy[j].x)+(U.y*zp[i].pxy[j].y)+(U.z*zp[i].z)+300);
pot.y=int((V.x*zp[i].pxy[j].x)+(V.y*zp[i].pxy[j].y)+(V.z*zp[i].z)+200);
return pot;
}//w_v()
Fpoint _w_v(int i,int j){
Fpoint pot;
pot.x=int((U.x*zp[i].pxy[j].x)+(U.y*zp[i].pxy[j].y)-(U.z*zp[i].z)+300);
pot.y=int((V.x*zp[i].pxy[j].x)+(V.y*zp[i].pxy[j].y)-(V.z*zp[i].z)+200);
return pot;
}//_w_v()
//..............................................................
bool seeable(int i,int j){
dcpt3 a,b,c,n;
if(i==dengfen/4)
{a.x=0.0; a.y=0.0; a.z=double(R);}//if
else
{a.x=zp[i].pxy[j].x; a.y=zp[i].pxy[j].y; a.z=zp[i].z;}
b.x=zp[i-1].pxy[j].x; b.y=zp[i-1].pxy[j].y; b.z=zp[i-1].z;
c.x=zp[i-1].pxy[j+1].x; c.y=zp[i-1].pxy[j+1].y; c.z=zp[i-1].z;
n.x=((b.y-a.y)*(c.z-b.z)-(b.z-a.z)*(c.y-b.y));
n.y=((b.z-a.z)*(c.x-b.x)-(b.x-a.x)*(c.z-b.z));
n.z=((b.x-a.x)*(c.y-b.y)-(b.y-a.y)*(c.x-b.x));
double k=n.x*(vw->x)+n.y*(vw->y)+n.z*(vw->z);
if(k<=0){
return true;}//if(k<=0)
else return false;
}//seeable()
bool _seeable(int i,int j){
dcpt3 a,b,c,n;
if(i==dengfen/4)
{a.x=0; a.y=0; a.z=-R;}//if
else
{ a.x=zp[i].pxy[j].x; a.y=zp[i].pxy[j].y; a.z=-zp[i].z;}
b.x=zp[i-1].pxy[j].x; b.y=zp[i-1].pxy[j].y; b.z=-zp[i-1].z;
c.x=zp[i-1].pxy[j+1].x; c.y=zp[i-1].pxy[j+1].y; c.z=-zp[i-1].z;
n.x=-((b.y-a.y)*(c.z-b.z)-(b.z-a.z)*(c.y-b.y));
n.y=-((b.z-a.z)*(c.x-b.x)-(b.x-a.x)*(c.z-b.z));
n.z=-((b.x-a.x)*(c.y-b.y)-(b.y-a.y)*(c.x-b.x));
double k=n.x*(vw->x)+n.y*(vw->y)+n.z*(vw->z);
if(k<=0) {
return true;}
else return false;
}//_seeable()______________________________________
bool seeable(int i,int j,Fpoint face[]){
dcpt3 a,b,c,n;
if(i==dengfen/4)
{a.x=0.0; a.y=0.0; a.z=double(R);}//if
else
{a.x=zp[i].pxy[j].x; a.y=zp[i].pxy[j].y; a.z=zp[i].z;}
b.x=zp[i-1].pxy[j].x; b.y=zp[i-1].pxy[j].y; b.z=zp[i-1].z;
c.x=zp[i-1].pxy[j+1].x; c.y=zp[i-1].pxy[j+1].y; c.z=zp[i-1].z;
n.x=((b.y-a.y)*(c.z-b.z)-(b.z-a.z)*(c.y-b.y));
n.y=((b.z-a.z)*(c.x-b.x)-(b.x-a.x)*(c.z-b.z));
n.z=((b.x-a.x)*(c.y-b.y)-(b.y-a.y)*(c.x-b.x));
double k=n.x*(vw->x)+n.y*(vw->y)+n.z*(vw->z);
if(k<=0){
if(m_bJingmian){
danweihua(n);
dcpt3 av;
av.x=viewpoint.x-a.x; av.y=viewpoint.y-a.y; av.z=viewpoint.z-a.z;
danweihua(av);
if(kd<0||kd>1) return false;
double I=-kd*Il*(n.x*av.x+n.y*av.y+n.z*av.z);
face[0].c.R=float(ForeColor.R+I);
if(face[0].c.R<0)face[0].c.R=0;
else if(face[0].c.R>255)face[0].c.R=255;
face[0].c.G=float(ForeColor.G+I);
if(face[0].c.G<0)face[0].c.G=0;
else if(face[0].c.G>255)face[0].c.G=255;
face[0].c.B=float(ForeColor.B+I);
if(face[0].c.B<0)face[0].c.B=0;
else if(face[0].c.B>255)face[0].c.B=255;
face[1].c.R=face[0].c.R; face[1].c.G=face[0].c.G; face[1].c.B=face[0].c.B;
face[2].c.R=face[0].c.R; face[2].c.G=face[0].c.G; face[2].c.B=face[0].c.B;
face[3].c.R=face[0].c.R; face[3].c.G=face[0].c.G; face[3].c.B=face[0].c.B;
}//if(m_bJingmian)
if(m_bFanshe){
dcpt3 v;
dcpt3 l,H; double NH;
double I;
if(i==dengfen/4){
n.x=0; n.y=0; n.z=1;
v.x=viewpoint.x; v.y=viewpoint.y; v.z=viewpoint.z-R;
danweihua(v);
I=-kd*Il*(n.x*v.x+n.y*v.y+n.z*v.z);
if(m_bGuangzhao){
l.x=lightpoint.x; l.y=lightpoint.y; l.z=lightpoint.z-R;
danweihua(l);
H.x=l.x+v.x; H.y=l.y+v.y; H.z=l.z+v.z;
danweihua(H);
NH=H.x*n.x+H.y*n.y+H.z*n.z;
I+=ks*Il*pow(NH,ns);
}//if_m_bGuangzhao
face[0].c.R=float(ForeColor.R+I);if(face[0].c.R<0)face[0].c.R=0;else if(face[0].c.R>255)face[0].c.R=255;
face[0].c.G=float(ForeColor.G+I);if(face[0].c.G<0)face[0].c.G=0;else if(face[0].c.G>255)face[0].c.G=255;
face[0].c.B=float(ForeColor.B+I);if(face[0].c.B<0)face[0].c.B=0;else if(face[0].c.B>255)face[0].c.B=255;
face[3].c.R=face[0].c.R; face[3].c.G=face[0].c.G; face[3].c.B=face[0].c.B;
}//if(i==dengfen/4)
else{
n=zp[i].pn[j];
v.x=viewpoint.x-zp[i].pxy[j].x;
v.y=viewpoint.y-zp[i].pxy[j].y;
v.z=viewpoint.z-zp[i].z;
danweihua(v);
I=-kd*Il*(n.x*v.x+n.y*v.y+n.z*v.z);
if(m_bGuangzhao){
l.x=lightpoint.x-zp[i].pxy[j].x;
l.y=lightpoint.y-zp[i].pxy[j].y;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -