Java3D中平行光投影的实现

理论根据:

假设一个光的方向是(-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);
}
}

时间: 2024-10-29 07:17:03

Java3D中平行光投影的实现的相关文章

java3d中setCoordinates()的用法

问题描述 java3d中setCoordinates()的用法 java3d中方法setCoordinates(int index, Point3f[] coordinates)中index的作用是什么呀?api说是索引,但是还是不知道具体的作用

数据点-WCF服务中的LINQ投影查询和替代方案

上个月当我的本地 .NET 用户组的演示者正在课堂上写 LINQ 查询时,我问他 ,"以前没有 LINQ 的时候,我们是怎么过的"?他回答说,"真是难以想象" . 这是真的.自从 2008 年 LINQ 被引入 Visual Studio 后,它对我们在 Microsoft .NET Framework 中的编程方式产生了如此 重大的影响.与 Visual Basic 和 C# 中引入的许多新的语言功能相结合,LINQ 可以前后一致地解决查 询内存中对象和数据来源的

《点睛:ActionScript3.0游戏互动编程》——2.2 Photoshop投影样式在Flash基本滤镜中的体现

2.2 Photoshop投影样式在Flash基本滤镜中的体现 作为上帝的另一个化身,Flash在图层样式方面自然也不甘示弱,不过在Flash里面,它有另外一个名字--滤镜(仅仅从概念上说,Flash的滤镜包含了Photoshop里的图层样式和滤镜). 下面打开Flash CS6/5.5,一起在滤镜里寻找Photoshop图层样式的影子,同时,我们先把Photoshop的图层样式暂时清除掉(把样式名称前面的复选框全部取消勾选即可). 我们先新建一个文档([文件]|[新建]或Ctrl+N),类型选

PS中隐藏的超炫文字功能

  提到Ps,我们和你一样,首先感受到的特别专业,特别绚丽,特别美好,也特别难学-- 但其实,Ps中的一些基础功能,既简单,又能实现高大上的效果.只是你不知道罢了-比如貌不惊人的文字工具. 看似简单的文字工具其实可以为我们的设计作品添加一系列神奇的文字特效.就像下图这样: 选择文字图层,单击图层面板下方的添加图层样式,从弹出菜单中选择投影.将投影的不透明度设为75%,角度30,距离16像素,扩散28.再创建一个新图层,将其置于文字图层下,添加白色到透明的径向渐变得到发光效果.         注

photoshop图层样式之投影功能介绍

在本文中我们将了解Photoshop图层样式中的投影,教程详细讲解了投影的各个选项的作用以及设置,对PS初学者了解PS的图层样式有很大帮助. 添加投影(Dropshadow)效果后,层的下方会出现一个轮廓和层的内容相同的"影子",这个影子有一定的偏移量,默认情况下会向右下角偏移.阴影的默认混合模式是正片叠底(Multiply),不透明度75%. 投影效果的选项有: 混合模式(Blend Mode) 颜色设置(Color) 不透明度(Opacity) 角度(Angle) 距离(Dista

新颖训练方法——用迭代投影算法训练神经网络

首发地址:https://yq.aliyun.com/articles/72738 作者介绍:Jesse Clark 研究相位恢复的物理学家.数据科学家,有着丰富的建设网站与设计手机应用的经验,在创业公司有着丰富的经验,对创业有着极大的热情.  Github: https://github.com/jn2clark Linkedin: http://www.linkedin.com/in/j3ss3cl4rk 相位恢复(PR)关心的是在给定幅度信息以及受到实空间限制下,找到复值函数(通常在傅立叶

观察:户外墙体激光投影成全球性趋势

一.LED拼接的阿喀琉斯之踵 近几年来,因人们对LED屏光污染的投诉不断增多,全国多个地市城管.环保等有关部门开始对对公共场所LED显示屏实施规范化管理,而这无疑使得LED显示屏的户外应用受到极大限制. 事实上,LED显示屏问题远不止光污染那么简单,其身上还夹带着与生俱来的弊端,束缚其应用的延展. LED显示屏安全问题,因LED显示屏着火引发的火灾事故几乎每年都有.或许一些火灾并非LED显示屏本身引起,只是殃及池鱼,但是led显示屏的安全性仍要提上日程.   图1 因LED显示屏着火引发的火灾事

3d-java3D中PickTool类怎么new

问题描述 java3D中PickTool类怎么new //检测是否发生碰撞 public static boolean isCollide(Point3d start, Point3d end){ PickTool pickTool = new PickTool(**branchGroup**); pickTool.setShapeSegment(start, end); if(pickTool.pickClosest()==null){ return true; } else return f

mapxtreme 坐标 投影 经纬度

问题描述 有谁帮忙解释一下mapxtreme中的投影跟坐标系和经纬度之间的关系?谢谢 解决方案 解决方案二:坐标系分为投影坐标系和地理坐标系,经纬度是地理坐标系,投影坐标系是为了便于计算将地理坐标系投影到平面..解决方案三:一般情况下,GIS中的坐标系可以分为投影坐标系和地理坐标系,地理坐标系通常就是我们所说的经纬度坐标,而投影坐标系则为了便于计算将地理坐标系投影到平面的XY值.表示方式不同.