Просто идея с нуля, а не окончательное решение.
Когда вы клонируете и переводите объект, для построения ar c между двумя соответствующими точками вам понадобятся их координаты в мировой системе координат, и координата средней точки между центроидами объектов.
- Найдите среднюю точку между точками в мировом пространстве (между начальным и конечным векторами).
- Найдите свою проекцию на вектор перевод (это центр ar c).
- Найдите угол между векторами, которые вы получаете путем вычитания вектора центра результата из каждого из них.
- Разделите угол на величину делений - вы получите значение шага.
- Получите конечный вектор в качестве основы и поверните его вокруг оси (которая является нормалью треугольника, построенного с начальными, центральными, конечными векторами) в oop, умножая это значение угла шага на номер текущей итерации.
Пример кода:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 10000);
camera.position.set(0, 0, 150);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var shapeGeom = new THREE.ShapeBufferGeometry(new THREE.Shape(californiaPts));
shapeGeom.center();
shapeGeom.scale(0.1, 0.1, 0.1);
var shapeMat = new THREE.MeshBasicMaterial({
color: "orange"
});
var shape = new THREE.Mesh(shapeGeom, shapeMat);
shape.updateMatrixWorld();
scene.add(shape);
var shapeClone = shape.clone();
shapeClone.position.set(25, 25, 0);
shapeClone.updateMatrixWorld();
scene.add(shapeClone);
var center = new THREE.Vector3().lerpVectors(shapeClone.position, shape.position, 0.5);
var vecStart = new THREE.Vector3();
var vecEnd = new THREE.Vector3();
var pos = shapeGeom.getAttribute("position");
for (let i = 0; i < pos.count; i++) {
vecStart.fromBufferAttribute(pos, i);
shape.localToWorld(vecStart);
vecEnd.fromBufferAttribute(pos, i);
shapeClone.localToWorld(vecEnd);
makeArc(center, vecStart, vecEnd);
}
function makeArc(center, start, end) {
console.log(center, start, end);
let vM = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);
let dir = new THREE.Vector3().subVectors(end, start).normalize();
let c = new THREE.Vector3().subVectors(vM, center);
let d = c.dot(dir);
c.copy(dir).multiplyScalar(d).add(center); // get a center of an arc
let vS = new THREE.Vector3().subVectors(start, c);
let vE = new THREE.Vector3().subVectors(end, c);
let a = vS.angleTo(vE); // andgle between start and end, relatively to the new center
let divisions = 100;
let aStep = a / divisions;
let pts = [];
let vecTemp = new THREE.Vector3();
let tri = new THREE.Triangle(start, c, end);
let axis = new THREE.Vector3();
tri.getNormal(axis); // get the axis to rotate around
for (let i = 0; i <= divisions; i++) {
vecTemp.copy(vE);
vecTemp.applyAxisAngle(axis, aStep * i);
pts.push(vecTemp.clone());
}
let g = new THREE.BufferGeometry().setFromPoints(pts);
let m = new THREE.LineDashedMaterial({
color: 0xff0000,
dashSize: 1,
gapSize: 1
});
let l = new THREE.Line(g, m);
l.computeLineDistances();
l.position.copy(c);
scene.add(l);
}
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>
var californiaPts = [
new THREE.Vector2(610, 320),
new THREE.Vector2(450, 300),
new THREE.Vector2(392, 392),
new THREE.Vector2(266, 438),
new THREE.Vector2(190, 570),
new THREE.Vector2(190, 600),
new THREE.Vector2(160, 620),
new THREE.Vector2(160, 650),
new THREE.Vector2(180, 640),
new THREE.Vector2(165, 680),
new THREE.Vector2(150, 670),
new THREE.Vector2(90, 737),
new THREE.Vector2(80, 795),
new THREE.Vector2(50, 835),
new THREE.Vector2(64, 870),
new THREE.Vector2(60, 945),
new THREE.Vector2(300, 945),
new THREE.Vector2(300, 743),
new THREE.Vector2(600, 473),
new THREE.Vector2(626, 425),
new THREE.Vector2(600, 370),
new THREE.Vector2(610, 320)
];
</script>
Если вы не переводите, а просто вращаете объект, в этом случае вам не нужно вычислять новый центр для каждого объекта. c, просто пропустите этот шаг, так как все центры равны центроиду объекта.
Надеюсь, я объяснил это более-менее понятно ^^