feat: Enable 3D constructions when adapting Geometry Applet #40
@ -16,8 +16,10 @@
|
||||
<br/>
|
||||
<br/>
|
||||
Alter execution of the translated applet: <br/>
|
||||
<label for="showall">Show all entities, even hidden ones</label>
|
||||
<input type="checkbox" id="showall">
|
||||
<label for="showall">Show all applet entities, even hidden ones</label>
|
||||
<input type="checkbox" id="showall"><br/>
|
||||
<label for="showaux">Show geogebra auxiliaries (not in applet)</label>
|
||||
<input type="checkbox" id="showaux">
|
||||
<script src="options.js" type="module"></script>
|
||||
</body>
|
||||
|
||||
|
@ -122,7 +122,11 @@ function freshCommander(): Commander
|
||||
type JoyceArguments =
|
||||
Partial<Record<JoyceClass|'subpoints', GeoName[]> & {scalar: number[]}>
|
||||
type ClassHandler = (
|
||||
name: GeoName, m: string, args: JoyceArguments, index: number) => Commander
|
||||
name: GeoName,
|
||||
method: string,
|
||||
args: JoyceArguments,
|
||||
index: number,
|
||||
is3d: boolean) => Commander
|
||||
type RGB = [number, number, number]
|
||||
type XYZ = RGB
|
||||
|
||||
@ -154,10 +158,12 @@ function dispatchJcommand(
|
||||
/e\[\d+\]/
|
||||
num := parseInt(name.slice(2))
|
||||
{commands, callbacks, parts} :=
|
||||
jToG value, elements, num, backgroundRGB
|
||||
jToG value, elements, num, backgroundRGB, is3d
|
||||
if commands.length
|
||||
lastTried .= 0
|
||||
if commands.filter((&)).every (cmd) =>
|
||||
if adapParams.config?.commands
|
||||
console.log 'Translated to:', cmd
|
||||
api.evalCommand(cmd) and ++lastTried
|
||||
callbacks.forEach &(api, parts)
|
||||
else console.warn
|
||||
@ -173,7 +179,8 @@ function jToG(
|
||||
jCom: string,
|
||||
elements: JoyceElements,
|
||||
index: number,
|
||||
backgroundRGB: RGB): Commander
|
||||
backgroundRGB: RGB
|
||||
is3d: boolean): Commander
|
||||
[jname, klass, method, data, ...colors] := jCom.split ';'
|
||||
if adapParams.config?.commands
|
||||
console.log 'Defining', jname, 'as a', klass, 'constructed by',
|
||||
@ -201,11 +208,11 @@ function jToG(
|
||||
(args.subpoints ?= []).push depGeo
|
||||
else if depKlass is 'line'
|
||||
(args.subpoints ?= []).push ...ends ?? []
|
||||
cmdr = classHandler[klass] name, method, args, index
|
||||
cmdr = classHandler[klass] name, method, args, index, is3d
|
||||
unless name is jname then cmdr.callbacks.push (api: AppletObject) =>
|
||||
api.setCaption name, jname
|
||||
api.setLabelStyle name, 3 // style CAPTION = 3
|
||||
if cmdr.auxiliaries.length
|
||||
if cmdr.auxiliaries.length and not adapParams.config?.showaux
|
||||
cmdr.callbacks.push (api: AppletObject) =>
|
||||
for each aux of cmdr.auxiliaries
|
||||
api.setAuxiliary aux, true
|
||||
@ -399,14 +406,14 @@ function geoname(jname: JoyceName, elements: JoyceElements): GeoName
|
||||
// All of the detailed semantics of each available command lies in this
|
||||
// function.
|
||||
classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
point: (name, method, args): Commander =>
|
||||
point: (name, method, args, index, is3d): Commander =>
|
||||
return := freshCommander()
|
||||
{commands, callbacks, parts, auxiliaries} := return.value
|
||||
aux := name + 'aUx'
|
||||
parts[0].push name
|
||||
switch method
|
||||
'angleDivider'
|
||||
// Note doesn't yet handle plane argument
|
||||
/angle(?:Bisector|Divider)/
|
||||
// Note we just ignore a possible plane argument; it's irrelevant
|
||||
unless args.subpoints return
|
||||
[start, center, end] := args.subpoints
|
||||
// see if we need to make the destination segment from start to end
|
||||
@ -416,11 +423,13 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
auxiliaries.push destination
|
||||
commands.push `${destination} = Segment(${start}, ${end})`
|
||||
else destination = args.line[0]
|
||||
n := args.scalar?[0]
|
||||
n := method is 'angleBisector' ? 2 : args.scalar?[0]
|
||||
console.log 'Dividing angle', start, center, end, 'by', n
|
||||
inPlane := is3d ? `, Plane(${start}, ${center}, ${end})` : ''
|
||||
commands.push
|
||||
`${aux}2 = Angle(${start}, ${center}, ${end})`
|
||||
`${aux}2 = Angle(${start}, ${center}, ${end}${inPlane})`
|
||||
`${aux}3 = If(${aux}2 > pi, ${aux}2 - 2*pi, ${aux}2)`
|
||||
`${aux}4 = Rotate(${start}, ${aux}3/${n}, ${center})`
|
||||
`${aux}4 = Rotate(${start}, ${aux}3/${n}, ${center}${inPlane})`
|
||||
`${name} = Intersect(${destination}, Ray(${center}, ${aux}4))`
|
||||
auxiliaries.push ...[2..4].map (i) => `${aux}${i}`
|
||||
'extend'
|
||||
@ -444,15 +453,19 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
'foot'
|
||||
pt := args.subpoints
|
||||
unless pt then return
|
||||
destination := args.plane
|
||||
? args.plane[0]
|
||||
: `Line(${pt[1]},${pt[2]})`
|
||||
commands.push
|
||||
`${name} = ClosestPoint(Line(${pt[1]},${pt[2]}), ${pt[0]})`
|
||||
`${name} = ClosestPoint(${destination}, ${pt[0]})`
|
||||
'intersection'
|
||||
// Checking Joyce source, means intersection of lines, not
|
||||
// intersection of line segments
|
||||
unless args.subpoints then return
|
||||
l1 := `Line(${args.subpoints[0]},${args.subpoints[1]})`
|
||||
l2 := `Line(${args.subpoints[2]},${args.subpoints[3]})`
|
||||
commands.push `${name} = Intersect(${l1},${l2})`
|
||||
pt := args.subpoints
|
||||
unless pt then return
|
||||
l1 := `Line(${pt[0]},${pt[1]})`
|
||||
e2 := args.plane ? args.plane[0] : `Line(${pt[2]},${pt[3]})`
|
||||
commands.push `${name} = Intersect(${l1},${e2})`
|
||||
'last'
|
||||
unless args.subpoints then return
|
||||
commands.push `${name} = ${args.subpoints.at(-1)}`
|
||||
@ -626,8 +639,22 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
// copy of the entity, and so we have to hide the original one
|
||||
api.setVisible name, false
|
||||
|
||||
plane: (name, method, args) => freshCommander()
|
||||
plane: (name, method, args) =>
|
||||
return := freshCommander()
|
||||
{commands, callbacks, parts, auxiliaries} := return.value
|
||||
parts[2].push name
|
||||
switch method
|
||||
'3points'
|
||||
unless args.subpoints?.length is 3 then return
|
||||
commands.push `${name} = Plane(${args.subpoints.join ','})`
|
||||
'perpendicular'
|
||||
unless args.subpoints?.length is 2 then return
|
||||
[thru, perp] := args.subpoints
|
||||
commands.push
|
||||
`${name} = PerpendicularPlane(${thru}, Line(${thru}, ${perp}))`
|
||||
|
||||
sphere: (name, method, args) => freshCommander()
|
||||
|
||||
polyhedron: (name, method, args, index) =>
|
||||
return := freshCommander()
|
||||
return.value.ends = ['', '']
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const flags = ['color', 'commands', 'showall'] as const
|
||||
export const flags = ['color', 'commands', 'showall', 'showaux'] as const
|
||||
export type FlagType = (typeof flags)[number]
|
||||
export type ConfigType = Partial<Record<FlagType, boolean>>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user