当前位置:网站首页>three物体围绕一周呈球形排列
three物体围绕一周呈球形排列
2022-08-05 09:54:00 【Jedi Hongbin】
圆形
思路: 根据指定半径的圆形 和需要物体存在的角度 计算点在圆上的坐标
/** * 根据一个模型生成一个围绕一圈的组合 */
export const modelSurround = (model: Object3D, radius: number, count: number) => {
const group = new THREE.Group();
const onceAngle = (Math.PI * 2) / 360; //一度
const spaceAngle = (360 / count) * onceAngle; //两个物体中间的夹角度数
for (let i = 1; i <= count; i++) {
const item = model.clone();
const x = Math.sin(spaceAngle * i) * radius;
const y = Math.cos(spaceAngle * i) * radius;
item.position.set(x, y, 0);
group.add(item);
}
return group;
};
调用
const model = new THREE.Mesh(
new THREE.BoxGeometry(3, 3, 3),
new THREE.MeshPhongMaterial({
color: 0xa88afa,
flatShading: true,
side: THREE.DoubleSide,
})
);
const roundModel = modelSurround(model, 10, 10);
scene.add(roundModel);
球形
/** * 根据一个模型生成一个围绕一圈的组合 */
export const modelSurround = (model: Object3D, radius: number, count: number, column: number = 1) => {
const group = new THREE.Group();
const onceAngle = (Math.PI * 2) / 360; //一度
const spaceAngle = (360 / count) * onceAngle; //两个物体中间的夹角度数
for (let l = 0; l < column; l++) {
const columnGroup = new THREE.Group();
for (let i = 0; i < count; i++) {
const item = model.clone();
const x = Math.sin(spaceAngle * i) * radius;
const y = Math.cos(spaceAngle * i) * radius;
item.position.set(x, y, 0);
columnGroup.add(item);
}
columnGroup.rotation.y = (180 / column) * onceAngle * l;
group.add(columnGroup);
}
return group;
};
调用
const model = new THREE.Mesh(
new THREE.BoxGeometry(3, 3, 3),
new THREE.MeshPhongMaterial({
color: 0xa88afa,
flatShading: true,
side: THREE.DoubleSide,
})
);
const roundModel = modelSurround(model, 10, 20, 8);
roundModel.position.y = 70;
scene.add(roundModel);
指定弧度 生成半圆
/** * 根据一个模型生成一个围绕一圈的组合 */
export const modelSurround = ({
model,
radius,
count,
radian = 360,
column = 1,
}: {
/** * 模型 */
model: Object3D;
/** * 半径 */
radius: number;
/** * 重复数量 */
count: number;
/** * 排列弧度默认360度(一周) * @default 360 */
radian?: number;
/** * 绕y轴旋转几列360列即为球形 默认1列 * @default 1 */
column?: number;
}) => {
const group = new THREE.Group();
const onceAngle = (Math.PI * 2) / 360; //一度
const spaceAngle = (radian / count) * onceAngle; //两个物体中间的夹角度数
for (let l = 0; l < column; l++) {
const columnGroup = new THREE.Group();
for (let i = 0; i < count; i++) {
const item = model.clone();
const x = Math.sin(spaceAngle * i) * radius;
const y = Math.cos(spaceAngle * i) * radius;
item.position.set(x, y, 0);
columnGroup.add(item);
}
columnGroup.rotation.y = (180 / column) * onceAngle * l;
group.add(columnGroup);
}
return group;
};
调用
const model = new THREE.Mesh(
new THREE.BoxGeometry(3, 3, 3),
new THREE.MeshPhongMaterial({
color: 0xa88afa,
flatShading: true,
side: THREE.DoubleSide,
})
);
const roundModel = modelSurround({
model, radius: 10, count: 10, radian: 90, column: 1 });
roundModel.position.y = 70;
scene.add(roundModel);
加入 多个模型随机选择排列
/** * 根据一个模型生成一个围绕一圈的组合 */
export const modelSurround = ({
model,
radius,
count,
radian = 360,
column = 1,
syncRotation = false,
}: {
/** * 模型 或者一个返回模型的函数 */
model: Object3D | (() => Object3D);
/** * 半径 */
radius: number;
/** * 重复数量 */
count: number;
/** * 排列弧度默认360度(一周) * @default 360 */
radian?: number;
/** * 绕y轴旋转几列360列即为球形 默认1列 * @default 1 */
column?: number;
/** * 旋转角度同步旋转 * @default false */
syncRotation?: boolean;
}) => {
const group = new THREE.Group();
const onceAngle = (Math.PI * 2) / 360; //一度
const spaceAngle = (radian / count) * onceAngle; //两个物体中间的夹角度数
for (let l = 0; l < column; l++) {
const columnGroup = new THREE.Group();
for (let i = 0; i < count; i++) {
const item = typeof model === "function" ? model().clone() : model.clone();
const x = Math.sin(spaceAngle * i) * radius;
const y = Math.cos(spaceAngle * i) * radius;
item.position.set(x, y, 0);
columnGroup.add(item);
syncRotation && (item.rotation.z = spaceAngle * -i);
}
columnGroup.rotation.y = (360 / column) * onceAngle * l;
group.add(columnGroup);
}
return group;
};
调用 传入一个随机生成的模型
/** * 获得三块砖的模型 */
const one = gltf.scene.getObjectByName("1");
const two = gltf.scene.getObjectByName("2");
const three = gltf.scene.getObjectByName("3");
if (!one || !two || !three) return;
const provider = [one, two, three];
const {
length: count } = provider;
const space = getSize(one).z + 1;
const blocksGroup = modelSurround({
model: () => {
const row = new Group();
for (let i = 0; i < count; i++) {
//随机获取得一个模型
const model = provider[Math.floor(Math.random() * count)].clone();
row.add(model);
//这样 0,1,2 是 0 3,4,5 是 1 有序排列保持坐标一致
const column = Math.floor(i / count);
const x = column * space;
const y = 0;
const z = (i % count) * space;
model.position.set(x, y, z);
}
return row;
},
count: 30,
radius: 460 * 4,
radian: 6,
syncRotation: true,
column: 4,
});
边栏推荐
- Neuron Newsletter 2022-07|新增非 A11 驱动、即将支持 OPC DA
- Pycharm 常用外部工具
- PAT乙级-B1021 个位数统计(15)
- egg框架使用(一)
- Jenkins manual (2) - software configuration
- IDEA performs the Test operation, resulting in duplicate data when data is inserted
- MQTT X Newsletter 2022-07 | 自动更新、MQTT X CLI 支持 MQTT 5.0、新增 conn 命令…
- 微服务 技术栈
- seata源码解析:事务状态及全局锁的存储
- mysql进阶(二十七)数据库索引原理
猜你喜欢
随机推荐
2022/8/4 考试总结
PAT乙级-B1021 个位数统计(15)
PAT Grade B-B1020 Mooncake(25)
自定义过滤器和拦截器实现ThreadLocal线程封闭
无题三
2022-08-01 Review the basic binary tree and operations
C语言的高级用法
MySQL内部函数介绍
Egg framework usage (2)
Qiu Jun, CEO of Eggplant Technology: Focus on users and make products that users really need
歌词整理
Can MySQL use aggregate functions without GROUP BY?
Neuron Newsletter 2022-07|新增非 A11 驱动、即将支持 OPC DA
Seata source code analysis: initialization process of TM RM client
深度学习21天——卷积神经网络(CNN):天气识别(第5天)
seata源码解析:事务状态及全局锁的存储
First Decentralized Heist?Loss of nearly 200 million US dollars: analysis of the attack on the cross-chain bridge Nomad
Tanabata romantic date without overtime, RPA robot helps you get the job done
js graphics operation one (compatible with pc, mobile terminal to achieve draggable attribute drag and drop effect)
2022.8.3