理论根据:
假设一个光的方向是(-1,-1,-1) , 投影到xz平面
一个是直线方程,一个是平面方程,求交
而且平面方程还比较特殊,经过原点,法向量是 0 1 0
简化后就简单了, 假定v是直线的方向
x - vertex.x y - vertex.y z-vertex.z
---------------- = --------------- = -------------- 直线方程
v.x v.y v.z
平面方程 y = 0
带入就得到了
x = vertex.x + v.x / v.y * (-vertex.y)
z = vertex.z + v.x / v.z * (-vertex.z)
源程序:
import java.applet.applet;
import java.awt.borderlayout;
import java.awt.graphicsconfiguration;
import java.awt.label;
import com.sun.j3d.utils.applet.mainframe;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class simpleshadow extends applet{
//三角平面类
public class triplane extends shape3d{
triplane(point3f a,point3f b,point3f c){
this.setgeometry(this.creategeometry3(a,b,c));
this.setappearance(this.createappearance());
}
//建立三角平面
geometry creategeometry3(point3f a,point3f b,point3f c){
trianglearray plane=new trianglearray(3,geometryarray.coordinates|geometryarray.normals);
//设置平面3个顶点的坐标
plane.setcoordinate(0,a);
plane.setcoordinate(1,b);
plane.setcoordinate(2,c);
//计算平面法向量
vector3f a=new vector3f(a.x-b.x,a.y-b.y,a.z-b.z);
vector3f b=new vector3f(c.x-b.x,c.y-b.y,c.z-b.z);
vector3f n=new vector3f();
n.cross(b,a);
//法向量单位化
n.normalize();
//设置平面3个顶点的法向量
plane.setnormal(0,n);
plane.setnormal(1,n);
plane.setnormal(2,n);
return plane;
}
//创建material不为空的外观
appearance createappearance(){
appearance appear=new appearance();
material material=new material();
appear.setmaterial(material);
return appear;
}
}
//四边平面类
public class quadplane extends shape3d{
quadplane(point3f a,point3f b,point3f c,point3f d){
this.setgeometry(this.creategeometry4(a,b,c,d));
this.setappearance(this.createappearance());
}
//创建四边性平面
geometry creategeometry4(point3f a,point3f b,point3f c,point3f d){
quadarray plane=new quadarray(4,geometryarray.coordinates|geometryarray.normals);
//设置平面3个顶点的坐标
plane.setcoordinate(0,a);
plane.setcoordinate(1,b);
plane.setcoordinate(2,c);
plane.setcoordinate(3,d);
//计算平面法向量
vector3f a=new vector3f(a.x-b.x,a.y-b.y,a.z-b.z);
vector3f b=new vector3f(c.x-b.x,c.y-b.y,c.z-b.z);
vector3f n=new vector3f();
n.cross(b,a);
//法向量单位化
n.normalize();
//设置平面4个顶点的法向量
plane.setnormal(0,n);
plane.setnormal(1,n);
plane.setnormal(2,n);
plane.setnormal(3,n);
return plane;
}
//创建material不为空的外观
appearance createappearance(){
appearance appear=new appearance();
material material=new material();
appear.setmaterial(material);
return appear;
}
}
//阴影类
public class shadow3d extends shape3d{
shadow3d(geometryarray geom,vector3f direction,color3f col,float height){
int vcount=geom.getvertexcount();
trianglearray poly=new trianglearray(vcount,geometryarray.coordinates|geometryarray.color_3);
int v;
point3f vertex=new point3f();
point3f shadow=new point3f();
for(v=0;v<vcount;v++){
//计算可见面顶点在投影面上的投影坐标
geom.getcoordinate(v,vertex);
system.out.println(vertex.y-height);
shadow.set(vertex.x-(vertex.y-height),height+0.0001f,vertex.z-(vertex.y-height));
poly.setcoordinate(v,shadow);
poly.setcolor(v,col);
}
this.setgeometry(poly);
}
}
public simpleshadow(){
this.setlayout(new borderlayout());
//graphicsconfiguration config =simpleuniverse.getpreferredconfiguration();
canvas3d c=new canvas3d(null);
this.add("center",c);
//创建分支节点
branchgroup scene=new branchgroup();
//创建三角形可见平面
shape3d plane=new triplane(new point3f(0.0f,0.6f,-0.2f),new point3f(-0.3f,-0.3f,0.2f),new point3f(0.6f,-0.3f,0.2f));
//添加到根分支节点
scene.addchild(plane);
//创建四边形投影平面
shape3d floor=new quadplane(new point3f(-1.0f,-0.5f,-1.0f),new point3f(-1.0f,-0.5f,1.0f),new point3f(1.0f,-0.5f,1.0f),new point3f(1.0f,-0.5f,-1.0f));
//添加到根分支节点
scene.addchild(floor);
//添加到环境光
ambientlight lighta=new ambientlight();
lighta.setinfluencingbounds(new boundingsphere());
scene.addchild(lighta);
//添加平行光
directionallight lightd1=new directionallight();
lightd1.setinfluencingbounds(new boundingsphere());
vector3f direction=new vector3f(-1.0f,-1.0f,-1.0f);
//方向矢量单位化
direction.normalize();
lightd1.setdirection(direction);
scene.addchild(lightd1);
//创建阴影物体
shape3d shadow=new shadow3d((geometryarray)plane.getgeometry(),direction,new color3f(0.2f,0.2f,0.2f),-0.5f);
scene.addchild(shadow);
simpleuniverse u=new simpleuniverse(c);
u.getviewingplatform().setnominalviewingtransform();
u.addbranchgraph(scene);
}
public static void main(string argv[]){
new mainframe(new simpleshadow(),256,256);
}
}
闽公网安备 35060202000074号