From 636f8bc560a5d6f83aebf4ab76cd7566123a4f79 Mon Sep 17 00:00:00 2001 From: howard Date: Mon, 12 Apr 2021 23:41:05 -0700 Subject: [PATCH] ugly but works --- src/Sketch.js | 16 +- src/drawAngle.js | 363 ++++++++++++++---------------------- src/drawDimension.js | 434 ++++++++++++++++++++++++++++++++++++------- src/mouseEvents.js | 14 +- 4 files changed, 523 insertions(+), 304 deletions(-) diff --git a/src/Sketch.js b/src/Sketch.js index cd9128a..ac70340 100644 --- a/src/Sketch.js +++ b/src/Sketch.js @@ -10,8 +10,8 @@ import { setCoincident, setOrdinate } from './constraintEvents' import { get3PtArc } from './drawArc' import { replacer, reviver } from './utils' import { AxesHelper } from './sketchAxes' -import { drawDimension, _onMoveDimension, setDimLines, updateDim } from './drawDimension'; -import { drawAngle, _onMoveAngle, setAngLines, updateAng } from './drawAngle'; +import { drawDimension, _onMoveDimension, setDimLines, updateDim, drawAngle } from './drawDimension'; +import { updateAng } from './drawAngle'; @@ -131,9 +131,9 @@ class Sketch { this.drawDimension = drawDimension.bind(this) this.drawAngle = drawAngle.bind(this) this._onMoveDimension = _onMoveDimension.bind(this) - this._onMoveAngle = _onMoveAngle.bind(this) + // this._onMoveAngle = _onMoveAngle.bind(this) this.setDimLines = setDimLines.bind(this) - this.setAngLines = setAngLines.bind(this) + // this.setAngLines = setAngLines.bind(this) this.updateDim = updateDim.bind(this) this.updateAng = updateAng.bind(this) @@ -223,11 +223,11 @@ class Sketch { this.mode = "arc" break; case 'd': - this.drawDimension() + this.drawDimension('d') this.mode = "" break; case 'q': - this.drawAngle() + this.drawDimension('a') this.mode = "" break; case 'p': @@ -482,10 +482,10 @@ class Sketch { } - // this.setDimLines() + this.setDimLines() // this.setAngLines() - this.obj3d.dispatchEvent({ type: 'change' }) + // this.obj3d.dispatchEvent({ type: 'change' }) } diff --git a/src/drawAngle.js b/src/drawAngle.js index c74d647..e49db27 100644 --- a/src/drawAngle.js +++ b/src/drawAngle.js @@ -18,97 +18,6 @@ const pointMaterial = new THREE.PointsMaterial({ const divisions = 12 -export async function drawAngle() { - let selection = await this.awaitSelection({ line: 2 }) - - if (selection == null) return; - - const line = new THREE.LineSegments( - new THREE.BufferGeometry().setAttribute('position', - new THREE.Float32BufferAttribute(Array((divisions + 2) * 2 * 3).fill(-0.001), 3) - ), - lineMaterial.clone() - ); - - const point = new THREE.Points( - new THREE.BufferGeometry().setAttribute('position', - new THREE.Float32BufferAttribute(3, 3) - ), - pointMaterial.clone() - ) - - line.userData.ids = selection.map(e => e.name) - - line.layers.enable(2) - point.layers.enable(2) - - let angle = getAngle(selection) - - - this.obj3d.children[1].add(line).add(point) - - const onMove = this._onMoveAngle(point, line) - - point.label = document.createElement('div'); - point.label.textContent = angle.toFixed(3); - point.label.contentEditable = true; - this.labelContainer.append(point.label) - - let onEnd, onKey; - let add = await new Promise((res) => { - onEnd = (e) => { - point.userData.offset = vecArr[5].toArray() - res(true) - } - onKey = (e) => e.key == 'Escape' && res(false) - - this.canvas.addEventListener('pointermove', onMove) - this.canvas.addEventListener('pointerdown', onEnd) - window.addEventListener('keydown', onKey) - }) - - this.canvas.removeEventListener('pointermove', onMove) - this.canvas.removeEventListener('pointerdown', onEnd) - window.removeEventListener('keydown', onKey) - point.geometry.computeBoundingSphere() - line.geometry.computeBoundingSphere() - - if (add) { - - this.constraints.set(++this.c_id, - [ - 'angle', angle, - [-1, -1, selection[0].name, selection[1].name] - ] - ) - - selection[0].userData.constraints.push(this.c_id) - selection[1].userData.constraints.push(this.c_id) - - this.updateOtherBuffers() - - line.name = this.c_id - line.userData.type = 'dimension' - point.name = this.c_id - point.userData.type = 'dimension' - - point.label.addEventListener('focus', this.updateAng(this.c_id)) - - } else { - - this.obj3d.children[1].children.splice(this.obj3d.children[1].length - 2, 2).forEach( - e => { - e.geometry.dispose() - e.material.dispose() - } - ) - this.labelContainer.removeChild(this.labelContainer.lastChild); - sc.render() - } - - return -} - export function updateAng(c_id) { @@ -136,74 +45,74 @@ export function updateAng(c_id) { } -let ids, _l1, _l2 -export function _onMoveAngle(point, line) { +// let ids, _l1, _l2 +// export function _onMoveAngle(point, line) { - ids = line.userData.ids +// ids = line.userData.ids - _l1 = this.obj3d.children[this.objIdx.get(ids[0])].geometry.attributes.position.array - _l2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array +// _l1 = this.obj3d.children[this.objIdx.get(ids[0])].geometry.attributes.position.array +// _l2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array - let loc; +// let loc; - return (e) => { - loc = this.getLocation(e) +// return (e) => { +// loc = this.getLocation(e) - p3.set(loc.x, loc.y) +// p3.set(loc.x, loc.y) - update( - line.geometry.attributes.position, - point.geometry.attributes.position, - _l1, _l2 - ) +// update( +// line.geometry.attributes.position, +// point.geometry.attributes.position, +// _l1, _l2 +// ) - // point.userData.offset = tagOffset.toArray() // save offset vector from center - // point.userData.offset = tagOffset // save offset vector from center - // tagOffset = undefined +// // point.userData.offset = tagOffset.toArray() // save offset vector from center +// // point.userData.offset = tagOffset // save offset vector from center +// // tagOffset = undefined - sc.render() - } -} +// sc.render() +// } +// } -export function setAngLines() { +// export function setAngLines() { - const restoreLabels = this.labelContainer.childElementCount == 0; +// const restoreLabels = this.labelContainer.childElementCount == 0; - const dims = this.obj3d.children[1].children +// const dims = this.obj3d.children[1].children - let point, dist; - for (let i = 0; i < dims.length; i += 2) { - // if (restoreLabels) { - // point = dims[i + 1] // point node is at i+1 - // dist = this.constraints.get(point.name)[1] - // point.label = document.createElement('div'); - // point.label.textContent = dist.toFixed(3); - // point.label.contentEditable = true; - // this.labelContainer.append(point.label) +// let point, dist; +// for (let i = 0; i < dims.length; i += 2) { +// // if (restoreLabels) { +// // point = dims[i + 1] // point node is at i+1 +// // dist = this.constraints.get(point.name)[1] +// // point.label = document.createElement('div'); +// // point.label.textContent = dist.toFixed(3); +// // point.label.contentEditable = true; +// // this.labelContainer.append(point.label) - // point.label.addEventListener('focus', this.updateAng(this.c_id)) - // } +// // point.label.addEventListener('focus', this.updateAng(this.c_id)) +// // } - ids = dims[i].userData.ids +// ids = dims[i].userData.ids - _l1 = this.obj3d.children[this.objIdx.get(ids[0])].geometry.attributes.position.array - _l2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array +// _l1 = this.obj3d.children[this.objIdx.get(ids[0])].geometry.attributes.position.array +// _l2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array - tagOffset = dims[i + 1].userData.offset +// tagOffset = dims[i + 1].userData.offset +// p3.set(_l1[0] + tagOffset[0], _l1[1] + tagOffset[1]) +// update( +// dims[i].geometry.attributes.position, +// dims[i + 1].geometry.attributes.position, +// _l1, +// _l2 +// ) +// } - update( - dims[i].geometry.attributes.position, - dims[i + 1].geometry.attributes.position, - _l1, - _l2 - ) - } - -} +// } @@ -271,120 +180,120 @@ const getAngle = (Obj3dLines) => { return deltaAngle / Math.PI * 180 } -function update(linegeom, pointgeom, _l1, _l2) { +// function update(linegeom, pointgeom, _l1, _l2) { - let i = 0; - for (; i < 4;) { - const arr = i == 0 ? _l1 : _l2 - vecArr[i++].set(arr[0], arr[1]) - vecArr[i++].set(arr[3] - arr[0], arr[4] - arr[1]) - } +// let i = 0; +// for (; i < 4;) { +// const arr = i == 0 ? _l1 : _l2 +// vecArr[i++].set(arr[0], arr[1]) +// vecArr[i++].set(arr[3] - arr[0], arr[4] - arr[1]) +// } - const centerScalar = findIntersection(...vecArr.slice(0, 4)) - const center = vecArr[i++].addVectors(vecArr[0], vecArr[1].clone().multiplyScalar(centerScalar)) +// const centerScalar = findIntersection(...vecArr.slice(0, 4)) +// const center = vecArr[4].addVectors(vecArr[0], vecArr[1].clone().multiplyScalar(centerScalar)) - if (tagOffset === undefined) { - vecArr[i++].subVectors(p3, center) - } else { - p3.set(center.x + tagOffset[0], center.y + tagOffset[1]) - vecArr[i++].subVectors(p3, center) - } +// // if (tagOffset === undefined) { +// // vecArr[5].subVectors(p3, center) +// // } else { +// // p3.set(center.x + tagOffset[0], center.y + tagOffset[1]) +// // } +// vecArr[5].subVectors(p3, center) - const tagRadius = vecArr[5].length() +// const tagRadius = vecArr[5].length() - /* - if tag is more than 90 deg away from midline, we shift everything by 180 +// /* +// if tag is more than 90 deg away from midline, we shift everything by 180 - a: array that describes absolute angular position of angle start, angle end, and tag +// a: array that describes absolute angular position of angle start, angle end, and tag - a[2]: - tag a[1]:angle end - \ | / - \ | / - ___\|/___ a[0]+dA/2:midline - / \ - / \ - / \ - a[0]:angle start - */ +// a[2]: +// tag a[1]:angle end +// \ | / +// \ | / +// ___\|/___ a[0]+dA/2:midline +// / \ +// / \ +// / \ +// a[0]:angle start +// */ - for (let j = 1, i = 0; j < vecArr.length; j += 2, i++) { - a[i] = Math.atan2(vecArr[j].y, vecArr[j].x) - } +// for (let j = 1, i = 0; j < vecArr.length; j += 2, i++) { +// a[i] = Math.atan2(vecArr[j].y, vecArr[j].x) +// } - let dA = unreflex(a[1] - a[0]) +// let dA = unreflex(a[1] - a[0]) - let tagtoMidline = unreflex(a[2] - (a[0] + dA / 2)) +// let tagtoMidline = unreflex(a[2] - (a[0] + dA / 2)) - let shift = Math.abs(tagtoMidline) < Math.PI / 2 ? 0 : Math.PI; +// let shift = Math.abs(tagtoMidline) < Math.PI / 2 ? 0 : Math.PI; - let tA1 = unreflex(a[2] - (a[0] + shift)) - let tA2 = unreflex(a[2] - (a[0] + dA + shift)) +// let tA1 = unreflex(a[2] - (a[0] + shift)) +// let tA2 = unreflex(a[2] - (a[0] + dA + shift)) - let a1, deltaAngle; - if (dA * tA1 < 0) { - a1 = a[0] + tA1 + shift - deltaAngle = dA - tA1 - } else if (dA * tA2 > 0) { - a1 = a[0] + shift - deltaAngle = dA + tA2 - } else { - a1 = a[0] + shift - deltaAngle = dA - } +// let a1, deltaAngle; +// if (dA * tA1 < 0) { +// a1 = a[0] + tA1 + shift +// deltaAngle = dA - tA1 +// } else if (dA * tA2 > 0) { +// a1 = a[0] + shift +// deltaAngle = dA + tA2 +// } else { +// a1 = a[0] + shift +// deltaAngle = dA +// } - let points = linegeom.array +// let points = linegeom.array - let d = 0; - points[d++] = center.x + tagRadius * Math.cos(a1) - points[d++] = center.y + tagRadius * Math.sin(a1) - d++ +// let d = 0; +// points[d++] = center.x + tagRadius * Math.cos(a1) +// points[d++] = center.y + tagRadius * Math.sin(a1) +// d++ - const angle = a1 + (1 / divisions) * deltaAngle - points[d++] = center.x + tagRadius * Math.cos(angle) - points[d++] = center.y + tagRadius * Math.sin(angle) - d++ +// const angle = a1 + (1 / divisions) * deltaAngle +// points[d++] = center.x + tagRadius * Math.cos(angle) +// points[d++] = center.y + tagRadius * Math.sin(angle) +// d++ - for (i = 2; i <= divisions; i++) { - points[d++] = points[d - 4] - points[d++] = points[d - 4] - d++ - const angle = a1 + (i / divisions) * deltaAngle - points[d++] = center.x + tagRadius * Math.cos(angle) - points[d++] = center.y + tagRadius * Math.sin(angle) - d++ - } +// for (i = 2; i <= divisions; i++) { +// points[d++] = points[d - 4] +// points[d++] = points[d - 4] +// d++ +// const angle = a1 + (i / divisions) * deltaAngle +// points[d++] = center.x + tagRadius * Math.cos(angle) +// points[d++] = center.y + tagRadius * Math.sin(angle) +// d++ +// } - for (i = 0; i < 2; i++) { - points[d++] = vecArr[2 * i].x - points[d++] = vecArr[2 * i].y - d++ - points[d++] = center.x + tagRadius * Math.cos(a[i] + shift) - points[d++] = center.y + tagRadius * Math.sin(a[i] + shift) - d++ - } +// for (i = 0; i < 2; i++) { +// points[d++] = vecArr[2 * i].x +// points[d++] = vecArr[2 * i].y +// d++ +// points[d++] = center.x + tagRadius * Math.cos(a[i] + shift) +// points[d++] = center.y + tagRadius * Math.sin(a[i] + shift) +// d++ +// } - linegeom.needsUpdate = true; +// linegeom.needsUpdate = true; - pointgeom.array.set(p3.toArray()) - pointgeom.needsUpdate = true; +// pointgeom.array.set(p3.toArray()) +// pointgeom.needsUpdate = true; -} +// } -const twoPi = Math.PI * 2 -const negTwoPi = - Math.PI * 2 -const negPi = - Math.PI +// const twoPi = Math.PI * 2 +// const negTwoPi = - Math.PI * 2 +// const negPi = - Math.PI -function unreflex(angle) { - if (angle > Math.PI) { - angle = negTwoPi + angle - } else if (angle < negPi) { - angle = twoPi + angle - } - return angle -} \ No newline at end of file +// function unreflex(angle) { +// if (angle > Math.PI) { +// angle = negTwoPi + angle +// } else if (angle < negPi) { +// angle = twoPi + angle +// } +// return angle +// } \ No newline at end of file diff --git a/src/drawDimension.js b/src/drawDimension.js index 2d6f5a5..853a7f0 100644 --- a/src/drawDimension.js +++ b/src/drawDimension.js @@ -13,22 +13,39 @@ const pointMaterial = new THREE.PointsMaterial({ }) -export async function drawDimension() { - let selection = await this.awaitSelection({ point: 2 }, { point: 1, line: 1 }) +export async function drawDimension(cc) { + ////////// + let selection + if (cc == 'd') { + selection = await this.awaitSelection({ point: 2 }, { point: 1, line: 1 }) + } else { + selection = await this.awaitSelection({ line: 2 }) + } + + ///////// if (selection == null) return; + let line; + if (cc == 'd') { + line = new THREE.LineSegments( + new THREE.BufferGeometry().setAttribute('position', + new THREE.Float32BufferAttribute(Array(3 * 8).fill(-0.001), 3) + ), + lineMaterial.clone() + ); + } else { + line = new THREE.LineSegments( + new THREE.BufferGeometry().setAttribute('position', + new THREE.Float32BufferAttribute(Array((divisions + 2) * 2 * 3).fill(-0.001), 3) + ), + lineMaterial.clone() + ); + } - const line = new THREE.LineSegments( - new THREE.BufferGeometry().setAttribute('position', - new THREE.Float32BufferAttribute(Array(3 * 8).fill(-0.001), 3) - ), - lineMaterial.clone() - ); - const point = new THREE.Points( new THREE.BufferGeometry().setAttribute('position', new THREE.Float32BufferAttribute(3, 3) @@ -42,52 +59,54 @@ export async function drawDimension() { point.layers.enable(2) + ////////////// + let dimVal, ptLineOrder; - let dist = 0 - let ptLineOrder; - - - - if (selection.every(e => e.userData.type == 'point')) { - for (let i = 0; i < 3; i++) { - dist += (selection[0].geometry.attributes.position.array[i] - selection[1].geometry.attributes.position.array[i]) ** 2 + if (cc == 'd') { + if (selection.every(e => e.userData.type == 'point')) { + for (let i = 0; i < 3; i++) { + dimVal += (selection[0].geometry.attributes.position.array[i] - selection[1].geometry.attributes.position.array[i]) ** 2 + } + dimVal = Math.sqrt(dimVal) + } else { + ptLineOrder = selection[0].userData.type == 'point' ? [0, 1] : [1, 0] + const ptArr = selection[ptLineOrder[0]].geometry.attributes.position.array + const lineArr = selection[ptLineOrder[1]].geometry.attributes.position.array + p1.set(lineArr[0], lineArr[1]) + p2.set(lineArr[3], lineArr[4]) + p3.set(ptArr[0], ptArr[1]) + dir = p2.clone().sub(p1).normalize() + disp = p3.clone().sub(p1) + proj = dir.multiplyScalar(disp.dot(dir)) + perpOffset = disp.clone().sub(proj) + dimVal = Math.sqrt(perpOffset.x ** 2 + perpOffset.y ** 2) } - - dist = Math.sqrt(dist) } else { - ptLineOrder = selection[0].userData.type == 'point' ? [0, 1] : [1, 0] - const ptArr = selection[ptLineOrder[0]].geometry.attributes.position.array - const lineArr = selection[ptLineOrder[1]].geometry.attributes.position.array - - - p1.set(lineArr[0], lineArr[1]) - p2.set(lineArr[3], lineArr[4]) - p3.set(ptArr[0], ptArr[1]) - dir = p2.clone().sub(p1).normalize() - disp = p3.clone().sub(p1) - proj = dir.multiplyScalar(disp.dot(dir)) - perpOffset = disp.clone().sub(proj) - - dist = Math.sqrt(perpOffset.x ** 2 + perpOffset.y ** 2) - + dimVal = getAngle(selection) } + //////////// + + this.obj3d.children[1].add(line).add(point) - const onMove = this._onMoveDimension(point, line) - point.label = document.createElement('div'); - point.label.textContent = dist.toFixed(3); + point.label.textContent = dimVal.toFixed(3); point.label.contentEditable = true; this.labelContainer.append(point.label) - - let onEnd, onKey; let add = await new Promise((res) => { - onEnd = (e) => res(true) + onEnd = (e) => { + if (cc == 'd') { + point.userData.offset = hyp2.toArray() // save offset vector from hyp2 + } else { + point.userData.offset = vecArr[5].toArray() + } + res(true) + } onKey = (e) => e.key == 'Escape' && res(false) this.canvas.addEventListener('pointermove', onMove) @@ -102,22 +121,33 @@ export async function drawDimension() { line.geometry.computeBoundingSphere() if (add) { - if (ptLineOrder) { - this.constraints.set(++this.c_id, //??? - [ - 'pt_line_distance', dist, - [selection[ptLineOrder[0]].name, -1, selection[ptLineOrder[1]].name, -1] - ] - ) + if (cc == 'd') { + if (ptLineOrder) { + this.constraints.set(++this.c_id, //??? + [ + 'pt_line_distance', dimVal, + [selection[ptLineOrder[0]].name, -1, selection[ptLineOrder[1]].name, -1] + ] + ) + } else { + this.constraints.set(++this.c_id, //??? + [ + 'pt_pt_distance', dimVal, + [selection[0].name, selection[1].name, -1, -1] + ] + ) + } } else { - this.constraints.set(++this.c_id, //??? + this.constraints.set(++this.c_id, [ - 'pt_pt_distance', dist, - [selection[0].name, selection[1].name, -1, -1] + 'angle', dimVal, + [-1, -1, selection[0].name, selection[1].name] ] ) } + + selection[0].userData.constraints.push(this.c_id) selection[1].userData.constraints.push(this.c_id) @@ -129,11 +159,9 @@ export async function drawDimension() { point.userData.type = 'dimension' - point.label.addEventListener('focus', this.updateDim(this.c_id)) - } else { this.obj3d.children[1].children.splice(this.obj3d.children[1].length - 2, 2).forEach( @@ -196,16 +224,13 @@ export function _onMoveDimension(point, line) { point.geometry.attributes.position, _p1, _p2 ) - // console.log('heree') - console.trace() - point.userData.offset = hyp2.toArray() // save offset vector from hyp2 + sc.render() } } - export function setDimLines() { const restoreLabels = this.labelContainer.childElementCount == 0; @@ -231,26 +256,29 @@ export function setDimLines() { _p2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array - const offset = dims[i + 1].userData.offset - if (_p1.length < _p2.length) { // corner case when p1 is pt and p2 is line - p3.set(_p1[0] + offset[0], _p1[1] + offset[1]) - } else { - p3.set(_p2[0] + offset[0], _p2[1] + offset[1]) - } - + let offset = dims[i + 1].userData.offset update( dims[i].geometry.attributes.position, dims[i + 1].geometry.attributes.position, _p1, - _p2 + _p2, + offset ) } } +export function onDimMoveEnd(point) { + if (hyp2) { + point.userData.offset = hyp2.toArray() // save offset vector from hyp2 + } else { + point.userData.offset = vecArr[5].clone().sub(vecArr[2]).toArray() + } +} + const p1 = new THREE.Vector2() let mdpt const p1x = new THREE.Vector2() @@ -263,7 +291,16 @@ let p1eArr, p2eArr, p3Arr let dir, linedir, perpOffset let dp1e, dp2e, dp12 -function update(linegeom, pointgeom, _p1, _p2) { +function updatex(linegeom, pointgeom, _p1, _p2, offset) { + + if (offset) { + if (_p1.length < _p2.length) { // corner case when p1 is pt and p2 is line + p3.set(_p1[0] + offset[0], _p1[1] + offset[1]) + } else { + p3.set(_p2[0] + offset[0], _p2[1] + offset[1]) + } + } + if (_p1.length == _p2.length) { p1.set(_p1[0], _p1[1]) @@ -352,4 +389,271 @@ function update(linegeom, pointgeom, _p1, _p2) { } +const divisions = 12 +export function findIntersection(q, s, p, r) { + /* + Based on: https://stackoverflow.com/questions/563198/ + q+s p+r + \/__________ q+u*s + /\ + / \ + p q + + u = (q − p) × r / (r × s) + when r × s = 0, the lines are either colinear or parallel + + function returns u + for "real" intersection to exist, 0 0) { + a1 = a[0] + shift + deltaAngle = dA + tA2 + } else { + a1 = a[0] + shift + deltaAngle = dA + } + + let points = linegeom.array + + let d = 0; + points[d++] = center.x + tagRadius * Math.cos(a1) + points[d++] = center.y + tagRadius * Math.sin(a1) + d++ + + const angle = a1 + (1 / divisions) * deltaAngle + points[d++] = center.x + tagRadius * Math.cos(angle) + points[d++] = center.y + tagRadius * Math.sin(angle) + d++ + + for (i = 2; i <= divisions; i++) { + points[d++] = points[d - 4] + points[d++] = points[d - 4] + d++ + const angle = a1 + (i / divisions) * deltaAngle + points[d++] = center.x + tagRadius * Math.cos(angle) + points[d++] = center.y + tagRadius * Math.sin(angle) + d++ + } + + + for (i = 0; i < 2; i++) { + points[d++] = vecArr[2 * i].x + points[d++] = vecArr[2 * i].y + d++ + points[d++] = center.x + tagRadius * Math.cos(a[i] + shift) + points[d++] = center.y + tagRadius * Math.sin(a[i] + shift) + d++ + } + + linegeom.needsUpdate = true; + + pointgeom.array.set(p3.toArray()) + pointgeom.needsUpdate = true; + + +} + + +const twoPi = Math.PI * 2 +const negTwoPi = - Math.PI * 2 +const negPi = - Math.PI + +function unreflex(angle) { + if (angle > Math.PI) { + angle = negTwoPi + angle + } else if (angle < negPi) { + angle = twoPi + angle + } + return angle +} + + + + +export async function drawAngle() { + ///////// + let selection = await this.awaitSelection({ line: 2 }) + ////////// + + if (selection == null) return; + + const line = new THREE.LineSegments( + new THREE.BufferGeometry().setAttribute('position', + new THREE.Float32BufferAttribute(Array((divisions + 2) * 2 * 3).fill(-0.001), 3) + ), + lineMaterial.clone() + ); + + const point = new THREE.Points( + new THREE.BufferGeometry().setAttribute('position', + new THREE.Float32BufferAttribute(3, 3) + ), + pointMaterial.clone() + ) + + line.userData.ids = selection.map(e => e.name) + + line.layers.enable(2) + point.layers.enable(2) + + + ///////////// + let angle = getAngle(selection) + ////////// + + + + + this.obj3d.children[1].add(line).add(point) + const onMove = this._onMoveDimension(point, line) + + point.label = document.createElement('div'); + point.label.textContent = angle.toFixed(3); + point.label.contentEditable = true; + this.labelContainer.append(point.label) + + let onEnd, onKey; + let add = await new Promise((res) => { + onEnd = (e) => { + point.userData.offset = vecArr[5].toArray() + res(true) + } + onKey = (e) => e.key == 'Escape' && res(false) + + this.canvas.addEventListener('pointermove', onMove) + this.canvas.addEventListener('pointerdown', onEnd) + window.addEventListener('keydown', onKey) + }) + + this.canvas.removeEventListener('pointermove', onMove) + this.canvas.removeEventListener('pointerdown', onEnd) + window.removeEventListener('keydown', onKey) + point.geometry.computeBoundingSphere() + line.geometry.computeBoundingSphere() + + if (add) { + + this.constraints.set(++this.c_id, + [ + 'angle', angle, + [-1, -1, selection[0].name, selection[1].name] + ] + ) + + + + + + + + selection[0].userData.constraints.push(this.c_id) + selection[1].userData.constraints.push(this.c_id) + + this.updateOtherBuffers() + + line.name = this.c_id + line.userData.type = 'dimension' + point.name = this.c_id + point.userData.type = 'dimension' + + point.label.addEventListener('focus', this.updateAng(this.c_id)) + + } else { + + this.obj3d.children[1].children.splice(this.obj3d.children[1].length - 2, 2).forEach( + e => { + e.geometry.dispose() + e.material.dispose() + } + ) + this.labelContainer.removeChild(this.labelContainer.lastChild); + sc.render() + } + + return +} + + +const getAngle = (Obj3dLines) => { + for (let i = 0; i < 2; i++) { + const arr = Obj3dLines[i].geometry.attributes.position.array + vecArr[2 * i].set(...arr.slice(0, 2)) + vecArr[2 * i + 1].set(arr[3] - arr[0], arr[4] - arr[1]) + } + const a1 = Math.atan2(vecArr[1].y, vecArr[1].x) + const a2 = Math.atan2(vecArr[3].y, vecArr[3].x) + + let deltaAngle = Math.abs(a2 - a1) + if (deltaAngle > Math.PI) { + deltaAngle = Math.PI * 2 - deltaAngle + } + return deltaAngle / Math.PI * 180 +} diff --git a/src/mouseEvents.js b/src/mouseEvents.js index 02000a7..dfa936c 100644 --- a/src/mouseEvents.js +++ b/src/mouseEvents.js @@ -1,6 +1,6 @@ import * as THREE from '../node_modules/three/src/Three'; import { raycaster, color, hoverColor } from './shared'; - +import { onDimMoveEnd } from './drawDimension' let ptLoc @@ -156,8 +156,15 @@ export function onPick(e) { this.obj3d.children[1].children[idx], this.obj3d.children[1].children[idx - 1], ) + // this.onDragDim = this._onMoveAng( + // this.obj3d.children[1].children[idx], + // this.obj3d.children[1].children[idx - 1], + // ) this.canvas.addEventListener('pointermove', this.onDragDim); - this.canvas.addEventListener('pointerup', this.onRelease) + this.canvas.addEventListener('pointerup', () => { + onDimMoveEnd(this.obj3d.children[1].children[idx]) + this.onRelease() + }) } draggedLabel = this.obj3d.children[1].children[idx].label @@ -196,7 +203,6 @@ export function onDrag(e) { // this.objIdx.get(obj.name) * 3 // ) - for (let x = 0; x < this.hovered.length; x++) { const obj = this.hovered[x] this.ptsBuf.set( @@ -206,7 +212,7 @@ export function onDrag(e) { } this.solve() - // this.obj3d.dispatchEvent({ type: 'change' }) + this.scene.render() }