JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>
function OffsetContour(offset, contour) {
let result = [];
offset = new THREE.BufferAttribute(new Float32Array([offset, 0, 0]), 3);
console.log("offset", offset);
for (let i = 0; i < contour.length; i++) {
let v1 = new THREE.Vector2().subVectors(contour[i - 1 < 0 ? contour.length - 1 : i - 1], contour[i]);
let v2 = new THREE.Vector2().subVectors(contour[i + 1 == contour.length ? 0 : i + 1], contour[i]);
let angle = v2.angle() - v1.angle();
let halfAngle = angle * 0.5;
let hA = halfAngle;
let tA = v2.angle() + Math.PI * 0.5;
let shift = Math.tan(hA - Math.PI * 0.5);
let shiftMatrix = new THREE.Matrix4().set(
1, 0, 0, 0,
-shift, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
let tempAngle = tA;
let rotationMatrix = new THREE.Matrix4().set(
Math.cos(tempAngle), -Math.sin(tempAngle), 0, 0,
Math.sin(tempAngle), Math.cos(tempAngle), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
let translationMatrix = new THREE.Matrix4().set(
1, 0, 0, contour[i].x,
0, 1, 0, contour[i].y,
0, 0, 1, 0,
0, 0, 0, 1,
);
let cloneOffset = offset.clone();
console.log("cloneOffset", cloneOffset);
shiftMatrix.applyToBufferAttribute(cloneOffset);
rotationMatrix.applyToBufferAttribute(cloneOffset);
translationMatrix.applyToBufferAttribute(cloneOffset);
result.push(new THREE.Vector2(cloneOffset.getX(0), cloneOffset.getY(0)));
}
debugger
return result;
}
</script>
CSS
body {
overflow: hidden;
margin: 0;
}
JavaScript
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 8, 1);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 0.75);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.25));
var helper = new THREE.GridHelper(8, 8);
scene.add(helper);
var contour1 = [
new THREE.Vector2(-0.1119572256903325,-0.14252051077050965),
new THREE.Vector2(0.10975718458439587,-0.14310303311816597),
new THREE.Vector2(0.11127948725177816,0.13894259858534497),
new THREE.Vector2(0.1068347874478377,0.13895764037215486),
new THREE.Vector2(0.06373126366580095,0.1395345664070078),
new THREE.Vector2(0.020626281121622014,0.1396804426163385),
new THREE.Vector2(-0.02247724266041473,0.14025736865119143),
new THREE.Vector2(-0.10868720774871575,0.1405491210701939),
new THREE.Vector2(-0.11087287440582827,0.1406220952283661),
];
const offsets = [-0.003592102448427661,-0.021552614690565967]
const color=['green','red']
for (let i = 0; i < 2; i++){
let points = OffsetContour(offsets[i], contour1);
console.log(points);
let geom = new THREE.BufferGeometry().setFromPoints(points);
geom.rotateX(-Math.PI * 0.5);
let line = new THREE.LineLoop(geom, new THREE.LineBasicMaterial({color: color[i]}));
scene.add(line);
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}