Three.js-如何检查对象是否在球体后面(不可见)
Three.js - How to check if object is behind a sphere (not visible)
我有一个球体(地球仪),表面上有对象(引脚),DOM元素(标签)从引脚位置到2d世界计算。
我的问题是,当引脚位于地球仪后面时(通过鼠标拖动或动画),我需要隐藏DOM中的标签,这样没有引脚就看不到文本标签。
我的逻辑是,如果我能得到3D世界中的大头针,告诉我它是否在地球仪后面,那么我就可以隐藏与大头针相关的标签。
用整个代码打开代码。
我一起研究的功能:
function checkPinVisibility() {
var startPoint = camera.position.clone();
for (var i = 0; i < pins.length; i++) {
var direction = pins[i].position.clone();
var directionVector = direction.sub(startPoint);
raycaster.set(startPoint, directionVector.clone().normalize());
var intersects = raycaster.intersectObject(pins[i]);
if (intersects.length > 0) {
// ?
}
}
}
我已经研究了很多帖子,但不能真正得到所需的结果:
- ThreeJS:如何检测对象是否呈现/可见
- Three.js-如何检查对象是否对相机可见
- http://soledadpenades.com/articles/three-js-tutorials/object-picking/
我已经通过鼠标XY位置将其作为光线来工作,但无法真正获得对所有引脚进行恒定渲染的工作解决方案。
您想知道球体表面上的哪些点对摄影机可见。
想象一下,来自摄影机的一条直线与球体相切。设L
为从摄影机到切点的直线的长度。
摄影机只能看到球体上比L
更靠近摄影机的点。
L
的公式为L = sqrt( D^2 - R^2 )
,其中D是从摄影机到球体中心的距离,R
是球体半径。
WestLangley的代码形式的解决方案。如果您觉得他的答案最好,请给他接受的答案。
function checkPinVisibility() {
var cameraToEarth = earth.position.clone().sub(camera.position);
var L = Math.sqrt(Math.pow(cameraToEarth.length(), 2) - Math.pow(earthGeometry.parameters.radius, 2));
for (var i = 0; i < pins.length; i++) {
var cameraToPin = pins[i].position.clone().sub(camera.position);
if(cameraToPin.length() > L) {
pins[i].domlabel.style.visibility = "hidden";
} else {
pins[i].domlabel.style.visibility = "visible";
}
}
}
奇怪的是,它仍然容易受到相机平移错误的影响。非常奇怪,但它仍然比我的投影到LOOKAT解决方案更好。
我以前的回答:
我本以为是这样的,但这似乎并没有像预期的那样奏效。
if (intersects.length > 0) {
pins[i].domlabel.style.visibility = "visible";
} else {
pins[i].domlabel.style.visibility = "hidden";
}
我很接近这个解决方案,但它仍然不完美。下面的代码的作用是找到相机沿LOOKAT方向到引脚的距离(cameraToPinProjection),并将其与沿LOOKET方向到地球的距离进行比较(cameraToEarthProjection)。如果cameraToPinProjection>cameraToEarthProjection,则表示引脚沿LOOKAT方向位于地球中心后面(然后我隐藏引脚)。
你会意识到,我把cameraToEarth投影乘以一个"0.8"因子。这是为了让它稍微短一点。试验一下。
这并不完美,因为当你绕着地球旋转时,你会注意到有时标签的行为并不像你想要的那样,我不知道如何修复。
我希望这能有所帮助。
function checkPinVisibility() {
var LOOKAT = new THREE.Vector3( 0, 0, -1 );
LOOKAT.applyQuaternion( camera.quaternion );
var cameraToEarth = earth.position.clone().sub(camera.position);
var angleToEarth = LOOKAT.angleTo(cameraToEarth);
var cameraToEarthProjection = LOOKAT.clone().normalize().multiplyScalar(0.8 * cameraToEarth.length() * Math.cos(angleToEarth));
var startPoint = camera.position.clone();
for (var i = 0; i < pins.length; i++) {
var cameraToPin = pins[i].position.clone().sub(camera.position);
var angleToPin = LOOKAT.angleTo(cameraToPin);
var cameraToPinProjection = LOOKAT.clone().normalize().multiplyScalar(cameraToPin.length() * Math.cos(angleToPin));
if(cameraToPinProjection.length() > cameraToEarthProjection.length()) {
pins[i].domlabel.style.visibility = "hidden";
} else {
pins[i].domlabel.style.visibility = "visible";
}
}
}
- 使用JS将数组转换为json对象
- 查看JS对象的所有键,甚至是getter定义的键
- 在URL中传递JS对象
- 为什么要包装每一个原型“;类“;JS中具有匿名函数的对象
- 当属性不一致时,如何根据属性对JS对象列表进行排序
- Node.js中的JavaScript原型对象效率
- 如何使用自定义功能覆盖时间轴对象.js时间轴对象的_repaintMinorText
- 如何在第三轴上旋转 3D 对象.js
- 三个中是否有容器类型对象.js来转换一组子对象
- 从 JSON 对象 - JS 周围删除双引号
- 删除对象JS中的节点
- 在对象数组中搜索非空对象JS
- 按未定义的值从数组中选择对象?JS
- 递归循环,直到我们'重新处理对象[JS]
- 向窗口对象-js添加新属性时得到通知
- 如何包含对象/关联数组到对象(js)
- 加载依赖于页面的面向对象JS属性的最好方法是什么?
- 合并新的数组对象到现有的对象js
- 获取带有下划线的数组中的对象.js
- 在带有下划线的嵌套集合中查找对象.js