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