当前位置:网站首页>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 are RELTABLESPACE values 0 for many tables displayed in sys_class?
- Going to book tickets tomorrow, ready to go home~~
- Four years of weight loss record
- 无题十二
- Egg framework usage (2)
- Egg framework usage (1)
- 21 Days of Deep Learning - Convolutional Neural Networks (CNN): Clothing Image Classification (Day 3)
- 无题十一
- 无题三
猜你喜欢

开源一夏|OpenHarmony如何查询设备类型(eTS)

leetcode: 529. Minesweeper Game

哪位大佬有20年4月或者1月的11G GI和ojvm补丁呀,帮忙发下?

手把手教你纯c实现异常捕获try-catch组件

Dry goods!Generative Model Evaluation and Diagnosis

什么是CRM决策分析管理?

蚁剑webshell动态加密连接分析与实践

Hundred lines of code launch red hearts, why programmers lose their girlfriends!

轩辕实验室丨欧盟EVITA项目预研 第一章(四)

2022.8.3
随机推荐
leetcode: 529. Minesweeper Game
js graphics operation one (compatible with pc, mobile terminal to achieve draggable attribute drag and drop effect)
tensorflow.keras cannot introduce layers
Keil升级到AC6后,到底有哪些变化?
韦东山 数码相框 项目学习(六)tslib的移植
蚁剑webshell动态加密连接分析与实践
egg框架使用(二)
Jenkins manual (2) - software configuration
手写柯里化 - toString 理解
PAT Level B - B1021 Single Digit Statistics (15)
无题十二
正则表达式replaceAll()方法具有什么功能呢?
First Decentralized Heist?Loss of nearly 200 million US dollars: analysis of the attack on the cross-chain bridge Nomad
Oracle temporary table space role
Four years of weight loss record
5. Deploy the web project to the cloud server
深度学习21天——卷积神经网络(CNN):服装图像分类(第3天)
公众号如何运维?公众号运维专业团队
IO stream articles -- based on io stream to realize folder copy (copy subfolders and files in subfolders) full of dry goods
What is the function of the regular expression replaceFirst() method?