Grid axis should be able to be selected for angles (#99)

This commit is contained in:
Kurt Hutten
2023-04-03 20:40:58 +10:00
committed by GitHub
parent a8b68bab6a
commit 8df08be687
4 changed files with 138 additions and 20 deletions

View File

@ -1,19 +1,32 @@
import { useStore } from '../useStore' import { useState } from 'react'
import { Selections, useStore } from '../useStore'
import { DoubleSide, Vector3, Quaternion } from 'three' import { DoubleSide, Vector3, Quaternion } from 'three'
import { Program } from '../lang/abstractSyntaxTree' import { Program } from '../lang/abstractSyntaxTree'
import { addNewSketchLn } from '../lang/std/sketch' import { addNewSketchLn } from '../lang/std/sketch'
import { roundOff } from '../lib/utils' import { roundOff } from '../lib/utils'
export const SketchPlane = () => { export const SketchPlane = () => {
const { ast, guiMode, updateAst, programMemory, updateAstAsync } = useStore( const {
(s) => ({ ast,
guiMode: s.guiMode, guiMode,
ast: s.ast, programMemory,
updateAst: s.updateAst, updateAstAsync,
updateAstAsync: s.updateAstAsync, setSelectionRanges,
programMemory: s.programMemory, selectionRanges,
}) isShiftDown,
) setCursor,
} = useStore((s) => ({
guiMode: s.guiMode,
ast: s.ast,
updateAstAsync: s.updateAstAsync,
programMemory: s.programMemory,
setSelectionRanges: s.setSelectionRanges,
selectionRanges: s.selectionRanges,
isShiftDown: s.isShiftDown,
setCursor: s.setCursor,
}))
const [xHover, setXHover] = useState(false)
const [yHover, setYHover] = useState(false)
if (guiMode.mode !== 'sketch') { if (guiMode.mode !== 'sketch') {
return null return null
} }
@ -35,6 +48,32 @@ export const SketchPlane = () => {
temp temp
) )
const onAxisClick = (name: 'y-axis' | 'x-axis') => () => {
const _selectionRanges: Selections = isShiftDown
? selectionRanges
: {
codeBasedSelections: [
{
range: [0, 0],
type: 'default',
},
],
otherSelections: [],
}
if (!isShiftDown) {
setCursor({
..._selectionRanges,
otherSelections: [name],
})
}
setTimeout(() => {
setSelectionRanges({
..._selectionRanges,
otherSelections: [name],
})
}, 100)
}
return ( return (
<> <>
<mesh <mesh
@ -86,10 +125,49 @@ export const SketchPlane = () => {
/> />
</mesh> </mesh>
<gridHelper <gridHelper
args={[30, 40, 'blue', 'hotpink']} args={[50, 50, 'blue', 'hotpink']}
quaternion={gridQuaternion} quaternion={gridQuaternion}
position={position} position={position}
onClick={() =>
!isShiftDown &&
setSelectionRanges({
...selectionRanges,
otherSelections: [],
})
}
/> />
<mesh
onPointerOver={() => setXHover(true)}
onPointerOut={() => setXHover(false)}
onClick={onAxisClick('x-axis')}
>
<boxGeometry args={[50, 0.2, 0.05]} />
<meshStandardMaterial
color={
selectionRanges.otherSelections.includes('x-axis')
? 'skyblue'
: xHover
? '#FF5555'
: '#FF1111'
}
/>
</mesh>
<mesh
onPointerOver={() => setYHover(true)}
onPointerOut={() => setYHover(false)}
onClick={onAxisClick('y-axis')}
>
<boxGeometry args={[0.2, 50, 0.05]} />
<meshStandardMaterial
color={
selectionRanges.otherSelections.includes('y-axis')
? 'skyblue'
: yHover
? '#5555FF'
: '#1111FF'
}
/>
</mesh>
</> </>
) )
} }

View File

@ -23,7 +23,7 @@ export const ConvertToVariable = () => {
const { isSafe, value } = isNodeSafeToReplace( const { isSafe, value } = isNodeSafeToReplace(
ast, ast,
selectionRanges.codeBasedSelections[0].range selectionRanges.codeBasedSelections?.[0]?.range || []
) )
const canReplace = isSafe && value.type !== 'Identifier' const canReplace = isSafe && value.type !== 'Identifier'
const isOnlyOneSelection = selectionRanges.codeBasedSelections.length === 1 const isOnlyOneSelection = selectionRanges.codeBasedSelections.length === 1

View File

@ -12,8 +12,13 @@ import {
transformAstSketchLines, transformAstSketchLines,
} from '../../lang/std/sketchcombos' } from '../../lang/std/sketchcombos'
import { SetAngleLengthModal } from '../SetAngleLengthModal' import { SetAngleLengthModal } from '../SetAngleLengthModal'
import { createVariableDeclaration } from '../../lang/modifyAst' import {
createBinaryExpressionWithUnary,
createIdentifier,
createVariableDeclaration,
} from '../../lang/modifyAst'
import { removeDoubleNegatives } from '../AvailableVarsHelpers' import { removeDoubleNegatives } from '../AvailableVarsHelpers'
import { normaliseAngle } from '../../lib/utils'
const getModalInfo = create(SetAngleLengthModal as any) const getModalInfo = create(SetAngleLengthModal as any)
@ -68,16 +73,47 @@ export const SetAngleLength = ({
referenceSegName: '', referenceSegName: '',
}) })
try { try {
const isReferencingYAxis =
selectionRanges.otherSelections.length === 1 &&
selectionRanges.otherSelections[0] === 'y-axis'
const isReferencingYAxisAngle =
isReferencingYAxis && angleOrLength === 'setAngle'
const isReferencingXAxis =
selectionRanges.otherSelections.length === 1 &&
selectionRanges.otherSelections[0] === 'x-axis'
const isReferencingXAxisAngle =
isReferencingXAxis && angleOrLength === 'setAngle'
let forceVal = valueUsedInTransform || 0
let calcIdentifier = createIdentifier('_0')
if (isReferencingYAxisAngle) {
calcIdentifier = createIdentifier(forceVal < 0 ? '_270' : '_90')
forceVal = normaliseAngle(forceVal + (forceVal < 0 ? 90 : -90))
} else if (isReferencingXAxisAngle) {
calcIdentifier = createIdentifier(
Math.abs(forceVal) > 90 ? '_180' : '_0'
)
forceVal =
Math.abs(forceVal) > 90
? normaliseAngle(forceVal - 180)
: forceVal
}
const { valueNode, variableName, newVariableInsertIndex, sign } = const { valueNode, variableName, newVariableInsertIndex, sign } =
await getModalInfo({ await getModalInfo({
value: valueUsedInTransform, value: forceVal,
valueName: angleOrLength === 'setAngle' ? 'angle' : 'length', valueName: angleOrLength === 'setAngle' ? 'angle' : 'length',
} as any) } as any)
const finalValue = removeDoubleNegatives( let finalValue = removeDoubleNegatives(valueNode, sign, variableName)
valueNode, if (
sign, isReferencingYAxisAngle ||
variableName (isReferencingXAxisAngle && calcIdentifier.name !== '_0')
) ) {
finalValue = createBinaryExpressionWithUnary([
calcIdentifier,
finalValue,
])
}
const { modifiedAst: _modifiedAst } = transformAstSketchLines({ const { modifiedAst: _modifiedAst } = transformAstSketchLines({
ast: JSON.parse(JSON.stringify(ast)), ast: JSON.parse(JSON.stringify(ast)),

View File

@ -20,6 +20,10 @@ export function getLength(a: [number, number], b: [number, number]): number {
export function getAngle(a: [number, number], b: [number, number]): number { export function getAngle(a: [number, number], b: [number, number]): number {
const x = b[0] - a[0] const x = b[0] - a[0]
const y = b[1] - a[1] const y = b[1] - a[1]
const result = ((Math.atan2(y, x) * 180) / Math.PI + 360) % 360 return normaliseAngle((Math.atan2(y, x) * 180) / Math.PI)
}
export function normaliseAngle(angle: number): number {
const result = ((angle % 360) + 360) % 360
return result > 180 ? result - 360 : result return result > 180 ? result - 360 : result
} }