mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2025-12-20 06:27:04 +01:00
fixes for distances
This commit is contained in:
@@ -1,51 +1,67 @@
|
|||||||
import {Vector3} from 'three';
|
import {BufferAttribute, InterleavedBufferAttribute, Vector3} from 'three';
|
||||||
import type {MObject3D} from "../tools/Selection.vue";
|
import type {MObject3D} from "../tools/Selection.vue";
|
||||||
|
|
||||||
|
|
||||||
|
function getCenterAndVertexList(obj: InstanceType<typeof MObject3D>): {
|
||||||
|
center: Vector3,
|
||||||
|
vertices: Array<Vector3>
|
||||||
|
} {
|
||||||
|
obj.updateMatrixWorld();
|
||||||
|
let pos: InterleavedBufferAttribute = obj.geometry.getAttribute('position');
|
||||||
|
let ind: BufferAttribute = obj.geometry.index;
|
||||||
|
let center = new Vector3();
|
||||||
|
let vertices = [];
|
||||||
|
for (let i = 0; i < ind.count; i++) {
|
||||||
|
let index = ind.array[i];
|
||||||
|
let vertex = new Vector3(pos.getX(index), pos.getY(index), pos.getZ(index));
|
||||||
|
// vertex = obj.localToWorld(vertex); // TODO: Bad locations due to with model viewer?
|
||||||
|
center.add(vertex);
|
||||||
|
vertices.push(vertex);
|
||||||
|
}
|
||||||
|
center = center.divideScalar(ind.count);
|
||||||
|
console.log("center", center)
|
||||||
|
return {center, vertices};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given two THREE.Object3D objects, returns their closest and farthest vertices, and the geometric centers.
|
* Given two THREE.Object3D objects, returns their closest and farthest vertices, and the geometric centers.
|
||||||
* All of them are approximated and should not be used for precise calculations.
|
* All of them are approximated and should not be used for precise calculations.
|
||||||
*/
|
*/
|
||||||
export function distances(
|
export function distances(a: InstanceType<typeof MObject3D>, b: InstanceType<typeof MObject3D>): {
|
||||||
a: InstanceType<typeof MObject3D>, b: InstanceType<typeof MObject3D>): {
|
|
||||||
min: Array<Vector3>,
|
min: Array<Vector3>,
|
||||||
center: Array<Vector3>,
|
center: Array<Vector3>,
|
||||||
max: Array<Vector3>
|
max: Array<Vector3>
|
||||||
} {
|
} {
|
||||||
// Simplify this problem (approximate) by using the distance between each of their vertices.
|
// Simplify this problem (approximate) by using the distance between each of their vertices.
|
||||||
|
// Find the center of each object.
|
||||||
|
let {center: aCenter, vertices: aVertices} = getCenterAndVertexList(a);
|
||||||
|
let {center: bCenter, vertices: bVertices} = getCenterAndVertexList(b);
|
||||||
|
|
||||||
|
// Find the closest and farthest vertices.
|
||||||
// TODO: Compute actual min and max distances between the two objects.
|
// TODO: Compute actual min and max distances between the two objects.
|
||||||
a.updateMatrixWorld();
|
|
||||||
b.updateMatrixWorld();
|
|
||||||
// FIXME: Working for points and lines, but not triangles...
|
// FIXME: Working for points and lines, but not triangles...
|
||||||
const aVertices = a.geometry.getAttribute('position').array;
|
// FIXME: Really slow... (use a BVH or something)
|
||||||
const aCenter = new Vector3();
|
|
||||||
const bVertices = b.geometry.getAttribute('position').array;
|
|
||||||
const bCenter = new Vector3();
|
|
||||||
let minDistance = Infinity;
|
let minDistance = Infinity;
|
||||||
let minDistanceVertices = [new Vector3(), new Vector3()];
|
let minDistanceVertices = [new Vector3(), new Vector3()];
|
||||||
let maxDistance = -Infinity;
|
let maxDistance = -Infinity;
|
||||||
let maxDistanceVertices = [new Vector3(), new Vector3()];
|
let maxDistanceVertices = [new Vector3(), new Vector3()];
|
||||||
for (let i = 0; i < aVertices.length; i += 3) {
|
for (let i = 0; i < aVertices.length; i++) {
|
||||||
const v = new Vector3(aVertices[i], aVertices[i + 1], aVertices[i + 2]);
|
for (let j = 0; j < bVertices.length; j++) {
|
||||||
//a.localToWorld(v);
|
let distance = aVertices[i].distanceTo(bVertices[j]);
|
||||||
aCenter.add(v);
|
if (distance < minDistance) {
|
||||||
for (let j = 0; j < bVertices.length; j += 3) {
|
minDistance = distance;
|
||||||
const w = new Vector3(bVertices[j], bVertices[j + 1], bVertices[j + 2]);
|
minDistanceVertices[0] = aVertices[i];
|
||||||
//b.localToWorld(w);
|
minDistanceVertices[1] = bVertices[j];
|
||||||
bCenter.add(w);
|
|
||||||
const d = v.distanceTo(w);
|
|
||||||
if (d < minDistance) {
|
|
||||||
minDistance = d;
|
|
||||||
minDistanceVertices = [v, w];
|
|
||||||
}
|
}
|
||||||
if (d > maxDistance) {
|
if (distance > maxDistance) {
|
||||||
maxDistance = d;
|
maxDistance = distance;
|
||||||
maxDistanceVertices = [v, w];
|
maxDistanceVertices[0] = aVertices[i];
|
||||||
|
maxDistanceVertices[1] = bVertices[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aCenter.divideScalar(aVertices.length / 3);
|
|
||||||
bCenter.divideScalar(bVertices.length / 3);
|
// Return the results.
|
||||||
return {
|
return {
|
||||||
min: minDistanceVertices,
|
min: minDistanceVertices,
|
||||||
center: [aCenter, bCenter],
|
center: [aCenter, bCenter],
|
||||||
|
|||||||
Reference in New Issue
Block a user