fix: hacks and bugfixes to get Book 13 working #59
@ -266,16 +266,21 @@ function jToG(
|
||||
if scalar is scalar // not NaN
|
||||
(args.scalar ?= []).push scalar
|
||||
continue
|
||||
unless jdep in cdata.elements
|
||||
console.warn `Reference to unknown geometric entity ${jdep} in $jCom}`
|
||||
return cmdr
|
||||
usesCaptions.push jdep
|
||||
{klass: depKlass, otherName: depGeo, ends} := cdata.elements[jdep]
|
||||
(args[depKlass] ?= []).push depGeo
|
||||
if depKlass is 'point'
|
||||
(args.subpoints ?= []).push depGeo
|
||||
else if depKlass is 'line'
|
||||
(args.subpoints ?= []).push ...ends ?? []
|
||||
if jdep is 'screen'
|
||||
// special case for Joyce; assume xOyPlane
|
||||
(args.plane ?= []).push 'xOyPlane'
|
||||
else
|
||||
unless jdep in cdata.elements
|
||||
console.warn
|
||||
`Reference to unknown geometric entity ${jdep} in ${jCom}`
|
||||
return cmdr
|
||||
usesCaptions.push jdep
|
||||
{klass: depKlass, otherName: depGeo, ends} := cdata.elements[jdep]
|
||||
(args[depKlass] ?= []).push depGeo
|
||||
if depKlass is 'point'
|
||||
(args.subpoints ?= []).push depGeo
|
||||
else if depKlass is 'line'
|
||||
(args.subpoints ?= []).push ...ends ?? []
|
||||
cmdr = classHandler[klass] name, method, args, index, cdata, colors, jname
|
||||
unless name is jname then cmdr.callbacks.push (api: AppletObject) =>
|
||||
api.setCaption name, jname
|
||||
@ -586,7 +591,7 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
aux := name + 'aUx'
|
||||
pivotable := cdata.pivot and name !== pivotData[cdata.pivot].pivot
|
||||
parts[0].push name
|
||||
// HACK: Special-case corrections for Joyce Elements Bk XI & XII
|
||||
// HACK: Special-case corrections for Joyce Elements Bk XI -- XIII
|
||||
if cdata.title is 'XI.4'
|
||||
if name is 'Z' and method is 'fixed' and args.scalar?.length is 3
|
||||
method = 'perpendicular'
|
||||
@ -614,6 +619,23 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
if (jname is 'a' and method is 'lineSlider'
|
||||
and args.subpoints?[1] is cdata.elements['1Y'].otherName)
|
||||
args.subpoints[1] = cdata.elements['1Z'].otherName
|
||||
if cdata.title is 'XIII.17'
|
||||
// Joyce's point perpendicular to a plane is ambiguous between
|
||||
// two possible positions, and Geogebra's choice does not
|
||||
// always agree with what Joyce's code did. So we just have to flip
|
||||
// one of his choices in the dodecahedron
|
||||
if name is 'U' and method is 'extend' and args.subpoints?[0] is "U'"
|
||||
method = 'midpoint'
|
||||
args.point = ["U'", "U'"] // hacky way to make U = U'
|
||||
if cdata.title is 'Dodecahedron and cube'
|
||||
// similar issues to XIII.17
|
||||
if (name is 'VAB' or name is 'VBC') and method is 'perpendicular'
|
||||
args.scalar = [1]
|
||||
if cdata.title is 'XIII.18'
|
||||
// Joyce just mistook where N is
|
||||
if name is 'N' and method is 'intersection'
|
||||
method = 'golden'
|
||||
args.subpoints = ['B', 'F']
|
||||
switch method
|
||||
/angle(?:Bisector|Divider)/
|
||||
{center, foot} :=
|
||||
@ -679,6 +701,12 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
: `Line(${pt[1]},${pt[2]})`
|
||||
commands.push
|
||||
`${name} = ClosestPoint(${destination}, ${pt[0]})`
|
||||
'golden'
|
||||
// Added in this implementation to ease fix of XIII.18
|
||||
pt := args.subpoints
|
||||
unless pt and pt.length is 2 then return
|
||||
commands.push
|
||||
`${name} = ${pt[0]} + ((sqrt(5)-1)/2)*(${pt[1]}-${pt[0]})`
|
||||
'intersection'
|
||||
// Checking Joyce source, means intersection of lines, not
|
||||
// intersection of line segments
|
||||
@ -736,15 +764,13 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
commands.push
|
||||
`${name} = Rotate(${pt[1]}, pi/2, ${center}${inPlane})`
|
||||
when 3 // perpendicular **to** the plane
|
||||
// Uses lots of auxiliaries
|
||||
radius := `Distance(${pt[1]}, ${pt[2]})`
|
||||
which := args.scalar ? args.scalar[0] : 2 //HACK: 2 vs 1??
|
||||
commands.push
|
||||
`${aux}1 = Circle(${center}, ${radius}${inPlane})`
|
||||
`${aux}2 = PointIn(${aux}1)`
|
||||
`${aux}3 = PerpendicularLine(${center}${inPlane})`
|
||||
`${aux}4 = Plane(${aux}2, ${aux}3)`
|
||||
`${name} = Rotate(${aux}2, pi/2, ${center}, ${aux}4)`
|
||||
auxiliaries.push aux+n for n of [1..4]
|
||||
`${aux}1 = Sphere(${center}, ${radius})`
|
||||
`${aux}2 = PerpendicularLine(${center}${inPlane})`
|
||||
`${name} = Intersect(${aux}2,${aux}1,${which})`
|
||||
auxiliaries.push aux+1, aux+2
|
||||
when 4
|
||||
commands.push
|
||||
`${aux}1 = Ray(${center}, Rotate(${pt[1]}, pi/2, ${center}${inPlane}))`
|
||||
@ -932,7 +958,6 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
aux := name + 'aUx'
|
||||
parts[1].push name
|
||||
circle .= ''
|
||||
defaultPlane := cdata.is3d ? ', xOyPlane' : ''
|
||||
switch method
|
||||
'circumcircle'
|
||||
pt := args.subpoints
|
||||
@ -944,18 +969,17 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
circle = `IntersectConic(${sph[0]}, ${sph[1]})`
|
||||
'radius'
|
||||
pt := args.subpoints
|
||||
unless pt then return
|
||||
inPlane := args.plane ? `, ${args.plane[0]}` : defaultPlane
|
||||
switch pt.length
|
||||
when 2
|
||||
[center, point] := pt
|
||||
ends[0] = center
|
||||
circle = `Circle(${center}, ${point}${inPlane})`
|
||||
when 3
|
||||
center := pt[0]
|
||||
ends[0] = center
|
||||
radius := `Distance(${pt[1]}, ${pt[2]})`
|
||||
circle = `Circle(${center}, ${radius}${inPlane})`
|
||||
unless pt and pt.length > 1 and pt.length < 4 then return
|
||||
ends[0] = pt[0]
|
||||
if pt.length is 2 and not cdata.is3d
|
||||
circle = `Circle(${pt[0]}, ${pt[1]})`
|
||||
else // 3d or three points
|
||||
radIx := pt.length - 2
|
||||
inPlane := (cdata.is3d
|
||||
? args.plane ? `, ${args.plane[0]}` : ', xOyPlane'
|
||||
: '')
|
||||
radius := `Distance(${pt[radIx]}, ${pt[radIx+1]})`
|
||||
circle = `Circle(${pt[0]}, ${radius}${inPlane})`
|
||||
commands.push
|
||||
`${aux} = ${circle}` // for the filling
|
||||
`${name} = ${circle}` // for the perimeter
|
||||
@ -978,9 +1002,14 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
N = args.scalar[0]
|
||||
commands.push '' // hack, make sure there is a command
|
||||
parts[0].push pt[0], pt[1]
|
||||
inPlane := cdata.is3d
|
||||
? args.plane ? `, ${args.plane[0]}` : ', xOyPlane'
|
||||
: ''
|
||||
callbacks.push (api: AppletObject, moreParts: DimParts) =>
|
||||
made:= api.evalCommandGetLabels
|
||||
`${name} = Polygon(${pt[0]},${pt[1]}, ${N})`
|
||||
command := `${name} = Polygon(${pt[0]},${pt[1]}, ${N}${inPlane})`
|
||||
made:= api.evalCommandGetLabels command
|
||||
if adapParams.config?.commands
|
||||
console.log 'Finishing with', command, 'producing', made
|
||||
if not made return
|
||||
for each obj of made.split ','
|
||||
if obj is name continue
|
||||
@ -1212,6 +1241,12 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
api.renameObject obj, newObj
|
||||
moreParts[1].push newObj
|
||||
base = ends[0]
|
||||
else // need to grab the parts of the base, which become
|
||||
// parts of the polyhedron
|
||||
baseParts := cdata.elements[base].parts
|
||||
if baseParts
|
||||
parts[0].push ...baseParts[0]
|
||||
parts[1].push ...baseParts[1]
|
||||
made := api.evalCommandGetLabels
|
||||
`${name} = Pyramid(${base}, ${ends[1]})`
|
||||
if not made return
|
||||
|
Loading…
Reference in New Issue
Block a user