当前位置:网站首页>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,
});
边栏推荐
- Why do I recommend using smart async?
- EU | Horizon 2020 ENSEMBLE: D2.13 SOTIF Safety Concept (Part 2)
- 使用工具类把对象中的null值转换为空字符串(集合也可以使用)
- Keil升级到AC6后,到底有哪些变化?
- Assembly language (8) x86 inline assembly
- 手写柯里化 - toString 理解
- 19. Server-side session technology Session
- 无题九
- 上海控安技术成果入选市经信委《2021年上海市网络安全产业创新攻关成果目录》
- Qiu Jun, CEO of Eggplant Technology: Focus on users and make products that users really need
猜你喜欢
随机推荐
ffmpeg drawtext 添加文本水印
正则表达式replaceAll()方法具有什么功能呢?
First Decentralized Heist?Loss of nearly 200 million US dollars: analysis of the attack on the cross-chain bridge Nomad
my journal link
MQTT X Newsletter 2022-07 | 自动更新、MQTT X CLI 支持 MQTT 5.0、新增 conn 命令…
Microservice Technology Stack
EU | Horizon 2020 ENSEMBLE: D2.13 SOTIF Safety Concept (Part 2)
Voice conversion相关语音数据集综合汇总
Can MySQL use aggregate functions without GROUP BY?
After Keil upgrades to AC6, what changes?
七夕浪漫约会不加班,RPA机器人帮你搞定工作
Which big guy has the 11G GI and ojvm patches in April or January 2020, please help?
无题七
无题六
什么是CRM决策分析管理?
【zeno】为zeno增加子模块/新节点的最小化的例子
语音社交软件开发——充分发挥其价值
ECCV 2022 Oral Video Instance Segmentation New SOTA: SeqFormer & IDOL and CVPR 2022 Video Instance Segmentation Competition Champion Scheme...
阿里顶级架构师多年总结的JVM宝典,哪里不会查哪里!
STM32+ULN2003驱动28BYJ4步进电机(根据圈数正转、反转)