diff --git a/icon/svgr_raw/arc.svg b/icon/svgr_raw/arc.svg
index 675f63c..e78e48e 100644
--- a/icon/svgr_raw/arc.svg
+++ b/icon/svgr_raw/arc.svg
@@ -23,22 +23,23 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="20.540932"
- inkscape:cx="3.3726703"
- inkscape:cy="-0.099609255"
+ inkscape:zoom="10.270466"
+ inkscape:cx="-9.1074268"
+ inkscape:cy="19.96038"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
inkscape:window-width="1514"
inkscape:window-height="1199"
- inkscape:window-x="1031"
- inkscape:window-y="111"
+ inkscape:window-x="550"
+ inkscape:window-y="74"
inkscape:window-maximized="0"
units="px"
inkscape:snap-object-midpoints="true"
inkscape:snap-text-baseline="true"
- inkscape:snap-center="true" />
+ inkscape:snap-center="true"
+ inkscape:snap-global="false" />
@@ -60,34 +61,64 @@
id="path1525"
sodipodi:type="arc"
sodipodi:cx="1.75"
- sodipodi:cy="13.631019"
+ sodipodi:cy="14.25"
sodipodi:rx="12.5"
sodipodi:ry="12.5"
- sodipodi:start="5.2879172"
- sodipodi:end="6.1912839"
+ sodipodi:start="4.8869219"
+ sodipodi:end="5.2708943"
sodipodi:arc-type="arc"
- d="M 8.5534749,3.1447071 A 12.5,12.5 0 0 1 14.19725,12.483867"
+ d="M 3.9206022,1.9399031 A 12.5,12.5 0 0 1 8.3739904,3.6493985"
sodipodi:open="true" />
-
+ x="0.75"
+ y="0.75" />
+ y="13.25" />
+
+
+
+
diff --git a/icon/svgr_raw/line.svg b/icon/svgr_raw/line.svg
index 57d6ad2..617fc4b 100644
--- a/icon/svgr_raw/line.svg
+++ b/icon/svgr_raw/line.svg
@@ -13,7 +13,7 @@
version="1.1"
id="svg2112"
inkscape:version="1.0.2 (1.0.2+r75+1)"
- sodipodi:docname="line.svg">
+ sodipodi:docname="line_alt.svg">
image/svg+xml
-
+
@@ -57,7 +57,7 @@
id="layer1">
+ y="4" />
+ y="10" />
+
diff --git a/src/Scene.js b/src/Scene.js
index be14a51..a284d0d 100644
--- a/src/Scene.js
+++ b/src/Scene.js
@@ -441,7 +441,7 @@ async function addSketch() {
}
window.sc = new Scene(store)
-sc.loadState()
+// sc.loadState()
// sc.camera.layers.enable(1)
// rc.layers.set(1)
\ No newline at end of file
diff --git a/src/Sketch.js b/src/Sketch.js
index 01bc2b0..6d2e89c 100644
--- a/src/Sketch.js
+++ b/src/Sketch.js
@@ -4,9 +4,9 @@ import * as THREE from '../node_modules/three/src/Three';
import { _vec2, _vec3, raycaster, awaitSelection, ptObj } from './shared'
-import { drawOnClick1, drawOnClick2, drawPreClick2, drawClear, drawPoint } from './drawEvents'
+import { drawOnClick1, drawOnClick2, drawPreClick2, drawOnClick3, drawPreClick3, drawClear, drawPoint } from './drawEvents'
import { onHover, onDrag, onPick, onRelease } from './mouseEvents'
-import { setCoincident, setOrdinate } from './constraintEvents'
+import { setCoincident, setOrdinate, setTangent } from './constraintEvents'
import { get3PtArc } from './drawArc'
import { replacer, reviver } from './utils'
import { AxesHelper } from './sketchAxes'
@@ -127,6 +127,9 @@ class Sketch {
this.drawPreClick2 = drawPreClick2.bind(this);
this.drawOnClick2 = drawOnClick2.bind(this);
+ this.drawPreClick3 = drawPreClick3.bind(this);
+ this.drawOnClick3 = drawOnClick3.bind(this);
+
this.drawDimension = drawDimension.bind(this)
this._onMoveDimension = _onMoveDimension.bind(this)
this.setDimLines = setDimLines.bind(this)
@@ -202,13 +205,13 @@ class Sketch {
onKeyPress(e) {
switch (e.key) {
case 'Escape':
- drawClear.bind(this)()
+ drawClear.call(this)
this.mode = ""
document.activeElement.blur()
break;
case 'l':
if (this.mode == 'line') {
- drawClear.bind(this)()
+ drawClear.call(this)
}
this.canvas.addEventListener('pointerdown', this.drawOnClick1)
this.mode = "line"
@@ -243,7 +246,10 @@ class Sketch {
setOrdinate.call(this, 1)
this.mode = ""
break;
-
+ case 't':
+ setTangent.call(this)
+ this.mode = ""
+ break;
case 'z':
var string = JSON.stringify(this.toJSON());
window.string = string;
@@ -340,7 +346,7 @@ class Sketch {
this.constraintsBuf.set(
[
this.constraintNum[obj[0]], obj[1],
- ...obj[2].map(ele => this.objIdx.get(ele) ?? -1),
+ ...obj[2].map(ele => this.objIdx.get(ele) ?? 0),
],
(i) * 6
)
@@ -459,7 +465,9 @@ class Sketch {
if (obj[0] != 'arc') continue;
const [p1, p2, c, arc] = obj[1].map(e => this.obj3d.children[this.objIdx.get(e)])
- const points = get3PtArc(
+ let points
+
+ points = get3PtArc(
p1.geometry.attributes.position.array,
p2.geometry.attributes.position.array,
c.geometry.attributes.position.array
@@ -469,15 +477,10 @@ class Sketch {
arc.needsUpdate = true;
}
-
this.setDimLines()
- // this.setAngLines()
-
- // this.obj3d.dispatchEvent({ type: 'change' })
}
-
}
const _m1 = new THREE.Matrix4()
diff --git a/src/constraintEvents.js b/src/constraintEvents.js
index 4081348..dca0e3f 100644
--- a/src/constraintEvents.js
+++ b/src/constraintEvents.js
@@ -1,4 +1,4 @@
-import {color} from './shared'
+import { color } from './shared'
export async function setCoincident() {
let selection = await this.awaitSelection({ point: 2 }, { point: 1, line: 1 })
@@ -12,12 +12,15 @@ export async function setCoincident() {
)
} else {
const idx = selection[0].userData.type == 'point' ? [0, 1] : [1, 0]
+
this.constraints.set(++this.c_id,
[
- 'pt_on_line', -1,
+ selection[idx[1]].userData.ccw !== undefined ? 'pt_on_circle' : 'pt_on_line'
+ , -1,
[selection[idx[0]].name, -1, selection[idx[1]].name, -1] ///////
]
)
+
}
selection[1].userData.constraints.push(this.c_id)
@@ -37,17 +40,63 @@ export async function setCoincident() {
}
-export function setOrdinate(dir = 0) {
+export async function setOrdinate(dir = 0) {
+ let selection = await this.awaitSelection({ point: 2 }, { line: 1 })
+ if (selection == null) return;
+ let arr
+ if (this.selected.length == 1) {
+ arr = [-1, -1, selection[0].name, -1]
+ } else {
+ arr = [selection[0].name, selection[1].name, -1, -1]
+ }
- const line = this.selected[0]
this.constraints.set(++this.c_id,
[
dir ? 'vertical' : 'horizontal', -1,
- [-1, -1, line.name, -1] ///////
+ arr
]
)
- line.userData.constraints.push(this.c_id)
+ selection.forEach(element => {
+ element.userData.constraints.push(this.c_id)
+ });
+
+
+ this.updateOtherBuffers()
+ this.solve()
+ this.updateBoundingSpheres()
+
+ this.selected = []
+ this.obj3d.dispatchEvent({ type: 'change' })
+}
+
+export async function setTangent() {
+ let selection = await this.awaitSelection({ line: 2 })
+ if (selection == null) return;
+
+ let idx = -1
+ for (let i = 0; i < 2; i++) {
+ if (selection[i].userData.ccw == undefined) {
+ idx = i
+ break
+ }
+ }
+
+ let arr = idx == 0 ?
+ [-1, -1, selection[1].name, selection[0].name] :
+ [-1, -1, selection[0].name, selection[1].name];
+
+ let type = idx == -1 ? 'curve_curve_tangent' : 'arc_line_tangent'
+
+ this.constraints.set(++this.c_id,
+ [
+ type, -1,
+ arr
+ ]
+ )
+ selection.forEach(element => {
+ element.userData.constraints.push(this.c_id)
+ });
this.updateOtherBuffers()
@@ -59,3 +108,4 @@ export function setOrdinate(dir = 0) {
}
+
diff --git a/src/drawArc.js b/src/drawArc.js
index b68df97..d2dc6fc 100644
--- a/src/drawArc.js
+++ b/src/drawArc.js
@@ -1,6 +1,7 @@
-import {ptObj, lineObj} from './shared'
+import { Vector2 } from 'three';
+import { ptObj, lineObj } from './shared'
const n = 30
@@ -9,13 +10,14 @@ export function drawArc(mouseLoc) {
const p1 = ptObj(mouseLoc)
p1.matrixAutoUpdate = false;
p1.userData.constraints = []
-
+
const p2 = ptObj()
p2.matrixAutoUpdate = false;
p2.userData.constraints = []
const arc = lineObj(n)
arc.frustumCulled = false;
+ arc.userData.constraints = []
const p3 = ptObj()
p3.matrixAutoUpdate = false;
@@ -44,6 +46,81 @@ export function drawArc2(mouseLoc, toPush) {
p3.geometry.computeBoundingSphere()
}
+
+
+const mdpt1 = new Vector2()
+const mdpt2 = new Vector2()
+const bis1 = new Vector2()
+const bis2 = new Vector2()
+const _vec2 = new Vector2()
+const _p1 = new Vector2()
+const _p2 = new Vector2()
+const _l12 = new Vector2()
+
+
+export function arcOnClick2(p1, p2) {
+ _p1.set(
+ p1.geometry.attributes.position.array[0],
+ p1.geometry.attributes.position.array[1]
+ )
+ _p2.set(
+ p2.geometry.attributes.position.array[0],
+ p2.geometry.attributes.position.array[1]
+ )
+ _l12.subVectors(_p2, _p1)
+ bis1.set(-_l12.y, _l12.x)
+ mdpt1.addVectors(_p1, _l12.multiplyScalar(0.5))
+}
+
+let r_cross_s, centerScalar, ccw, points
+export function drawArc3(mouseLoc, toPush) {
+ const [p1, p2, p3, arc] = toPush
+
+ _vec2.set(mouseLoc.x - _p1.x, mouseLoc.y - _p1.y)
+
+ ccw = _l12.cross(_vec2) < 0 ? 1 : 0;
+
+ bis2.set(-_vec2.y, _vec2.x)
+ mdpt2.addVectors(_p1, _vec2.multiplyScalar(0.5))
+
+ // https://stackoverflow.com/questions/563198/
+ r_cross_s = bis1.cross(bis2);
+ if (r_cross_s === 0) {
+ centerScalar = 0.5
+ } else {
+ centerScalar = _vec2.subVectors(mdpt2, mdpt1).cross(bis1) / r_cross_s;
+ }
+
+ p3.geometry.attributes.position.set(
+ _vec2.addVectors(mdpt2, bis2.multiplyScalar(centerScalar)).toArray()
+ );
+
+ p3.geometry.attributes.position.needsUpdate = true;
+ p3.geometry.computeBoundingSphere()
+
+ if (ccw) {
+ points = get3PtArc(
+ p1.geometry.attributes.position.array,
+ p2.geometry.attributes.position.array,
+ p3.geometry.attributes.position.array
+ )
+ } else {
+ points = get3PtArc(
+ p2.geometry.attributes.position.array,
+ p1.geometry.attributes.position.array,
+ p3.geometry.attributes.position.array
+ )
+ }
+
+ arc.geometry.attributes.position.set(
+ points
+ );
+ arc.geometry.attributes.position.needsUpdate = true;
+ arc.userData.ccw = ccw;
+
+ return ccw
+}
+
export function get2PtArc(p1, p2, divisions = n) {
const dx = p2[0] - p1[0]
@@ -85,7 +162,7 @@ export function get3PtArc(p1, p2, c, divisions = n) {
let deltaAngle = a2 - a1
- if (deltaAngle <=0) deltaAngle += Math.PI*2
+ if (deltaAngle <= 0) deltaAngle += Math.PI * 2
// let deltaAngle = a2 - a1
// if (deltaAngle > Math.PI ){
@@ -99,7 +176,7 @@ export function get3PtArc(p1, p2, c, divisions = n) {
// deltaAngle = Math.PI*2 - deltaAngle
// }
-
+
let points = new Float32Array((divisions + 1) * 3)
for (let d = 0; d <= divisions; d++) {
@@ -115,7 +192,7 @@ export function getAngleArc(a1, a2, c, radius, divisions = n) {
let deltaAngle = a2 - a1
-
+
let points = new Float32Array((divisions + 1) * 3)
for (let d = 0; d <= divisions; d++) {
diff --git a/src/drawDimension.js b/src/drawDimension.js
index 9b5de07..f98722b 100644
--- a/src/drawDimension.js
+++ b/src/drawDimension.js
@@ -314,7 +314,6 @@ function updateDistance(linegeom, pointgeom, _p1, _p2, offset) {
proj1 = dir.clone().multiplyScalar(hyp1.dot(dir))
hyp2 = tagPos.clone().sub(p2) // note that this value is used to calculate tag-p2 offset
- console.log(hyp2, 'hereeeeee')
proj2 = dir.clone().multiplyScalar(hyp2.dot(dir))
p1eArr = tagPos.clone().sub(proj1).toArray()
diff --git a/src/drawEvents.js b/src/drawEvents.js
index 1273bd2..924c369 100644
--- a/src/drawEvents.js
+++ b/src/drawEvents.js
@@ -1,5 +1,5 @@
-import { drawArc, drawArc2 } from './drawArc'
+import { drawArc, drawArc2, arcOnClick2, drawArc3 } from './drawArc'
import { drawLine, drawLine2 } from './drawLine'
import { ptObj } from './shared'
@@ -15,10 +15,8 @@ export function drawOnClick1(e) {
this.toPush = drawLine.call(this, mouseLoc)
} else if (this.mode == "arc") {
this.toPush = drawArc(mouseLoc)
- } else if (this.mode == 'dim') {
- this.curDimension = drawDimension.call(this)
} else if (this.mode == 'point') {
- this.toPush = drawPoint.call(this, mouseLoc)
+ this.toPush = drawPoint(mouseLoc)
}
this.toPush.forEach(element => {
@@ -61,28 +59,43 @@ export function drawOnClick2(e) {
this.subsequent = true
this.drawOnClick1(e)
- } else if (this.mode == "arc") {
- // this.toPush = []
- // this.canvas.addEventListener('pointermove', this.drawPreClick3)
- // this.canvas.addEventListener('pointerdown', this.drawOnClick3)
} else if (this.mode == "point") {
this.drawOnClick1(e)
+ } else if (this.mode == "arc") {
+
+ arcOnClick2(this.toPush[0], this.toPush[1])
+
+ this.canvas.addEventListener('pointermove', this.drawPreClick3)
+ this.canvas.addEventListener('pointerdown', this.drawOnClick3)
}
}
+let ccw;
export function drawPreClick3(e) {
- const mouseLoc = this.getLocation(e).toArray();
-
+ const mouseLoc = this.getLocation(e);
+ ccw = drawArc3(mouseLoc, this.toPush)
sc.render()
}
-
export function drawOnClick3(e) {
if (e.buttons !== 1) return;
this.canvas.removeEventListener('pointermove', this.drawPreClick3);
this.canvas.removeEventListener('pointerdown', this.drawOnClick3);
+ if (!ccw) {
+ let temp
+ const ent = this.linkedObjs.get(this.l_id - 1)
+ temp = ent[1][0]
+ ent[1][0] = ent[1][1]
+ ent[1][1] = temp
+ this.linkedObjs.set(this.l_id - 1, ent)
+ let i = (this.linkedObjs.size - 1) * 5
+ temp = this.linksBuf[i + 1]
+ this.linksBuf[i + 1] = this.linksBuf[i + 2]
+ this.linksBuf[i + 2] = temp
+ }
+ this.canvas.addEventListener('pointerdown', this.drawOnClick1)
}
@@ -97,6 +110,18 @@ export function drawClear() {
this.delete(this.obj3d.children[this.updatePoint])
+ this.obj3d.dispatchEvent({ type: 'change' })
+ this.subsequent = false
+ this.toPush = []
+ } if (this.mode == "arc") {
+ this.canvas.removeEventListener('pointerdown', this.drawOnClick1)
+ this.canvas.removeEventListener('pointermove', this.drawPreClick2);
+ this.canvas.removeEventListener('pointerdown', this.drawOnClick2);
+ this.canvas.removeEventListener('pointermove', this.drawPreClick3);
+ this.canvas.removeEventListener('pointerdown', this.drawOnClick3);
+
+ this.delete(this.obj3d.children[this.updatePoint])
+
this.obj3d.dispatchEvent({ type: 'change' })
this.subsequent = false
this.toPush = []
diff --git a/src/react/icons.jsx b/src/react/icons.jsx
index 1ecd465..dfaf4e5 100644
--- a/src/react/icons.jsx
+++ b/src/react/icons.jsx
@@ -8,17 +8,25 @@ function Arc(props) {
viewBox="0 0 16 16"
{...props}
>
-
-
-
-
+
+
+
+
+
);
}
@@ -355,10 +363,14 @@ function Line(props) {
{...props}
>
-
+
@@ -437,6 +449,29 @@ function Subtract(props) {
);
}
+function Tangent(props) {
+ return (
+
+ );
+}
+
function Union(props) {
return (