我正在尝试编写一个函数,该函数将获取三个顶点并在由这些顶点形成的边界平面上的任意位置返回一个随机点。因此该功能将如下所示:
function randomPointOnPlane(vertex1, vertex2, vertex3) {
...
return THREE.Vector3( x, y, z ); // random point on bounded plane
}
我的方法是尝试解决ax + by + cz + d = 0给出的方程组,该方程组用于定义边界平面的每个顶点。我还没有走的很远!我应该怎么做?谢谢
答案 0 :(得分:1)
我建议使用以下工作流程:使用Plane.setFromCoplanarPoints()从三个方面创建一个THREE.Plane
对象。然后,您可以在3D空间中创建一个随机点(例如,通过Math.random()
),然后通过Plane.projectPoint()在平面上投影该点。这将是您预期功能的结果。
答案 1 :(得分:0)
//这里有一个基于重心坐标的算法... https://adamswaab.wordpress.com/2009/12/11/random-point-in-a-triangle-barycentric-coordinates/
function randomPointInTriangle(vertex1, vertex2, vertex3) {
var edgeAB = vertex2.clone().sub(vertex1)
var edgeAC = vertex3.clone().sub(vertex1)
var r = Math.random();
var s = Math.random();
if (r + s >= 1) {
r = 1 - r
s = 1 - s
}
return edgeAB.multiplyScalar(r).add(edgeAC.multiplyScalar(s)).add(vertex1)
// random point in triangle
}
var renderer = new THREE.WebGLRenderer();
var w = 300;
var h = 200;
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
45, // Field of view
w / h, // Aspect ratio
0.1, // Near
10000 // Far
);
camera.position.set(15, 10, 15);
camera.lookAt(scene.position);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.PointLight(0xFFFF00);
light.position.set(20, 20, 20);
scene.add(light);
var light1 = new THREE.AmbientLight(0x808080);
light1.position.set(20, 20, 20);
scene.add(light1);
var light2 = new THREE.PointLight(0x00FFFF);
light2.position.set(-20, 20, -20);
scene.add(light2);
var light3 = new THREE.PointLight(0xFF00FF);
light3.position.set(-20, -20, -20);
scene.add(light3);
var sphereGeom = new THREE.SphereGeometry(0.1, 8, 8);
sphereGeom.verticesNeedUpdate = true;
sphereGeom.computeFaceNormals();
sphereGeom.computeVertexNormals();
function randomPointInTriangle(vertex1, vertex2, vertex3) {
var edgeAB = vertex2.clone().sub(vertex1)
var edgeAC = vertex3.clone().sub(vertex1)
var r = Math.random();
var s = Math.random();
if (r + s >= 1) {
r = 1 - r
s = 1 - s
}
return edgeAB.multiplyScalar(r).add(edgeAC.multiplyScalar(s)).add(vertex1)
// random point in triangle
}
var material = new THREE.MeshLambertMaterial({
color: 0x808080
});
var v0 = new THREE.Vector3(0, 0, -2)
var v1 = new THREE.Vector3(2, 0, 1)
var v2 = new THREE.Vector3(-2, 0, 1)
for (var i = 0; i < 500; i++) {
var mesh = new THREE.Mesh(sphereGeom, material);
mesh.position.copy(randomPointInTriangle(v0, v1, v2))
scene.add(mesh);
}
renderer.setClearColor(0xdddddd, 1);
(function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
})();
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
答案 2 :(得分:0)
要均匀地采样成三角形,请使用以下函数:
function randomInTriangle(v1, v2, v3) {
var r1 = Math.random();
var r2 = Math.sqrt(Math.random());
var a = 1 - r2;
var b = r2 * (1 - r1);
var c = r1 * r2;
return (v1.clone().multiplyScalar(a)).add(v2.clone().multiplyScalar(b)).add(v3.clone().multiplyScalar(c));
function randomInTriangle(v1, v2, v3) {
var r1 = Math.random();
var r2 = Math.sqrt(Math.random());
var a = 1 - r2;
var b = r2 * (1 - r1);
var c = r1 * r2;
return (v1.clone().multiplyScalar(a)).add(v2.clone().multiplyScalar(b)).add(v3.clone().multiplyScalar(c));
}
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
scene.add(camera);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var v0 = new THREE.Vector3(0, 0, 1);
var v1 = new THREE.Vector3(0, 1, 0);
var v2 = new THREE.Vector3(1, 0, 0);
var material = new THREE.PointsMaterial({
color: 0xff0000,
size: 0.05,
opacity: 1
});
var geometry = new THREE.Geometry();
for (var i = 0; i < 100; i++) {
var pt = randomInTriangle(v0, v1, v2);
geometry.vertices.push(pt);
}
var pointCloud = new THREE.Points(geometry, material);
scene.add(pointCloud);
function render() {
renderer.render(scene, camera);
pointCloud.rotation.x += 0.01;
pointCloud.rotation.y += 0.01;
requestAnimationFrame(render);
}
render();
<script src="https://threejs.org/build/three.min.js"></script>