feat: complete commands needed for Book Eleven
This commit is contained in:
parent
e10da118a7
commit
c903a42f89
@ -67,6 +67,7 @@ type ConstructionData
|
|||||||
height: number
|
height: number
|
||||||
elements: JoyceElements
|
elements: JoyceElements
|
||||||
pivot: string
|
pivot: string
|
||||||
|
title?: string
|
||||||
|
|
||||||
// Global data setup for pivoting (ugh, but necessary because the api
|
// Global data setup for pivoting (ugh, but necessary because the api
|
||||||
// is not passed to the callback, so we have to look up the slider in
|
// is not passed to the callback, so we have to look up the slider in
|
||||||
@ -186,7 +187,8 @@ type ClassHandler = (
|
|||||||
method: string,
|
method: string,
|
||||||
args: JoyceArguments,
|
args: JoyceArguments,
|
||||||
index: number,
|
index: number,
|
||||||
cdata: ConstructionData) => Commander
|
cdata: ConstructionData,
|
||||||
|
colors: string[]) => Commander
|
||||||
type RGB = [number, number, number]
|
type RGB = [number, number, number]
|
||||||
type XYZ = RGB
|
type XYZ = RGB
|
||||||
|
|
||||||
@ -208,6 +210,7 @@ function dispatchJcommand(
|
|||||||
'title'
|
'title'
|
||||||
if adapParams.config?.commands
|
if adapParams.config?.commands
|
||||||
console.log 'Setting title to', value
|
console.log 'Setting title to', value
|
||||||
|
cdata.title = value
|
||||||
api.evalCommand `TitlePoint = Corner(1,1)
|
api.evalCommand `TitlePoint = Corner(1,1)
|
||||||
Text("${value}", TitlePoint + (2,5))`
|
Text("${value}", TitlePoint + (2,5))`
|
||||||
'pivot'
|
'pivot'
|
||||||
@ -257,7 +260,7 @@ function jToG(
|
|||||||
args: JoyceArguments := {}
|
args: JoyceArguments := {}
|
||||||
usesCaptions := []
|
usesCaptions := []
|
||||||
for each jdep of data.split ','
|
for each jdep of data.split ','
|
||||||
scalar := parseFloat jdep
|
scalar := Number jdep
|
||||||
if scalar is scalar // not NaN
|
if scalar is scalar // not NaN
|
||||||
(args.scalar ?= []).push scalar
|
(args.scalar ?= []).push scalar
|
||||||
continue
|
continue
|
||||||
@ -271,7 +274,7 @@ 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, cdata
|
cmdr = classHandler[klass] name, method, args, index, cdata, colors
|
||||||
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
|
||||||
@ -517,7 +520,7 @@ function pointDefaultColorName(
|
|||||||
|
|
||||||
function geoname(
|
function geoname(
|
||||||
jname: JoyceName, elements: JoyceElements, klass: JoyceClass): GeoName
|
jname: JoyceName, elements: JoyceElements, klass: JoyceClass): GeoName
|
||||||
unless jname.substring(0,3) is 'Geo' // those might clash
|
unless jname is 'floor' or jname.substring(0,3) is 'Geo' // those might clash
|
||||||
// Names with word characters starting with a capital are always good:
|
// Names with word characters starting with a capital are always good:
|
||||||
if /^[A-Z]['\w]*$/.test jname then return jname
|
if /^[A-Z]['\w]*$/.test jname then return jname
|
||||||
// If it's not a point, can start with any letter:
|
// If it's not a point, can start with any letter:
|
||||||
@ -571,7 +574,7 @@ function proportionSimilar(
|
|||||||
// 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, index, cdata): Commander =>
|
point: (name, method, args, index, cdata, colors): Commander =>
|
||||||
return := freshCommander()
|
return := freshCommander()
|
||||||
{commands, callbacks, parts, auxiliaries} := return.value
|
{commands, callbacks, parts, auxiliaries} := return.value
|
||||||
zeroVector := cdata.is3d ? 'Vector((0,0,0))' : 'Vector((0,0))'
|
zeroVector := cdata.is3d ? 'Vector((0,0,0))' : 'Vector((0,0))'
|
||||||
@ -579,6 +582,22 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
aux := name + 'aUx'
|
aux := name + 'aUx'
|
||||||
pivotable := cdata.pivot and name !== pivotData[cdata.pivot].pivot
|
pivotable := cdata.pivot and name !== pivotData[cdata.pivot].pivot
|
||||||
parts[0].push name
|
parts[0].push name
|
||||||
|
// HACK: Special-case corrections for Joyce Elements Bk XI
|
||||||
|
if cdata.title is 'XI.4'
|
||||||
|
if name is 'Z' and method is 'fixed' and args.scalar?.length is 3
|
||||||
|
method = 'perpendicular'
|
||||||
|
args.subpoints = ['E','P2','A']
|
||||||
|
args.plane = ['baseplane']
|
||||||
|
colors[0] = '0'
|
||||||
|
colors[1] = '0'
|
||||||
|
if name is 'F' and method is 'lineSlider' and args.subpoints?[0] is 'E'
|
||||||
|
args.scalar = [160,40,60]
|
||||||
|
if cdata.title is 'XI.5'
|
||||||
|
if name is 'A' and method is 'free'
|
||||||
|
method = 'perpendicular'
|
||||||
|
args.subpoints = ['B','P1','P3']
|
||||||
|
args.plane = ['xOyPlane']
|
||||||
|
commands.push 'B=(80,140)'
|
||||||
switch method
|
switch method
|
||||||
/angle(?:Bisector|Divider)/
|
/angle(?:Bisector|Divider)/
|
||||||
{center, foot} :=
|
{center, foot} :=
|
||||||
@ -608,6 +627,12 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
if args.scalar and args.scalar.length
|
if args.scalar and args.scalar.length
|
||||||
callbacks.push (api: AppletObject) =>
|
callbacks.push (api: AppletObject) =>
|
||||||
api.setCoords name, ...vertFlipped(args.scalar or [], cdata)
|
api.setCoords name, ...vertFlipped(args.scalar or [], cdata)
|
||||||
|
'circumcenter'
|
||||||
|
unless args.subpoints?.length is 3 then return
|
||||||
|
commands.push
|
||||||
|
`${aux} = Circle(${args.subpoints.join ','})`
|
||||||
|
`${name} = Center(${aux})`
|
||||||
|
auxiliaries.push aux
|
||||||
/cutoff|extend/
|
/cutoff|extend/
|
||||||
pt := args.subpoints
|
pt := args.subpoints
|
||||||
unless pt and pt.length is 4 then return
|
unless pt and pt.length is 4 then return
|
||||||
@ -616,9 +641,9 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
commands.push `${name} = Translate(${source}, ${displacement})`
|
commands.push `${name} = Translate(${source}, ${displacement})`
|
||||||
'first'
|
'first'
|
||||||
unless args.subpoints then return
|
unless args.subpoints then return
|
||||||
// HACK: Special-case correction for Joyce Elements Bk II, prop 14
|
|
||||||
index .= 0
|
index .= 0
|
||||||
if name === 'H' and args.line and args.line[0] === 'HH2'
|
// HACK: Special-case correction for Joyce Elements Bk II, prop 14
|
||||||
|
if cdata.title is 'II.14' and name is 'H' and args.line?[0] is 'HH2'
|
||||||
index = 1
|
index = 1
|
||||||
commands.push `${name} = ${args.subpoints[index]}`
|
commands.push `${name} = ${args.subpoints[index]}`
|
||||||
/fixed|free/
|
/fixed|free/
|
||||||
@ -642,9 +667,9 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
// Checking Joyce source, means intersection of lines, not
|
// Checking Joyce source, means intersection of lines, not
|
||||||
// intersection of line segments
|
// intersection of line segments
|
||||||
pt := args.subpoints
|
pt := args.subpoints
|
||||||
unless pt then return
|
unless pt and pt.length > 1 then return
|
||||||
l1 := `Line(${pt[0]},${pt[1]})`
|
l1 := `Line(${pt[0]},${pt[1]})`
|
||||||
e2 := args.plane ? args.plane[0] : `Line(${pt[2]},${pt[3]})`
|
e2 := pt.length < 3 ? args.plane?[0] : `Line(${pt[2]},${pt[3]})`
|
||||||
commands.push `${name} = Intersect(${l1},${e2})`
|
commands.push `${name} = Intersect(${l1},${e2})`
|
||||||
'last'
|
'last'
|
||||||
unless args.subpoints then return
|
unless args.subpoints then return
|
||||||
@ -696,8 +721,9 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
`${name} = Rotate(${pt[1]}, pi/2, ${center}${inPlane})`
|
`${name} = Rotate(${pt[1]}, pi/2, ${center}${inPlane})`
|
||||||
when 3 // perpendicular **to** the plane
|
when 3 // perpendicular **to** the plane
|
||||||
// Uses lots of auxiliaries
|
// Uses lots of auxiliaries
|
||||||
|
radius := `Distance(${pt[1]}, ${pt[2]})`
|
||||||
commands.push
|
commands.push
|
||||||
`${aux}1 = Circle(${center}, Distance(${pt[1]}, ${pt[2]})${inPlane})`
|
`${aux}1 = Circle(${center}, ${radius}${inPlane})`
|
||||||
`${aux}2 = PointIn(${aux}1)`
|
`${aux}2 = PointIn(${aux}1)`
|
||||||
`${aux}3 = PerpendicularLine(${center}${inPlane})`
|
`${aux}3 = PerpendicularLine(${center}${inPlane})`
|
||||||
`${aux}4 = Plane(${aux}2, ${aux}3)`
|
`${aux}4 = Plane(${aux}2, ${aux}3)`
|
||||||
@ -847,7 +873,17 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
commands.push
|
commands.push
|
||||||
`${aux} = Rotate(${pt[1]}, pi/2, ${pt[0]}${inPlane})`
|
`${aux} = Rotate(${pt[1]}, pi/2, ${pt[0]}${inPlane})`
|
||||||
when 3
|
when 3
|
||||||
return // TODO: line perpendicular to plane
|
radius := `Distance(${pt[1]}, ${pt[2]})`
|
||||||
|
commands.push
|
||||||
|
`${aux}1 = PerpendicularLine(${pt[1]}${inPlane})`
|
||||||
|
`${aux}2 = Intersect(${aux}1${inPlane})`
|
||||||
|
`${aux}3 = Circle(${aux}2, ${radius}${inPlane})`
|
||||||
|
`${aux}4 = PointIn(${aux}3)`
|
||||||
|
`${aux}5 = Plane(${aux}4, ${aux}1)`
|
||||||
|
`${aux}6 = Rotate(${aux}4, pi/2, ${aux}2, ${aux}5)`
|
||||||
|
ends[0] = aux + 2
|
||||||
|
ends[1] = aux + 6
|
||||||
|
auxiliaries.push aux+n for n of [1..6]
|
||||||
when 4
|
when 4
|
||||||
ends[0] = pt[0]
|
ends[0] = pt[0]
|
||||||
ends[1] = aux + 2
|
ends[1] = aux + 2
|
||||||
@ -998,7 +1034,7 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
aux := name + 'aUx'
|
aux := name + 'aUx'
|
||||||
parts[2].push name
|
parts[2].push name
|
||||||
defaultPlane := cdata.is3d ? ', xOyPlane' : ''
|
defaultPlane := cdata.is3d ? ', xOyPlane' : ''
|
||||||
inPlane := args.plane ? `, ${args.plane[0]}` : defaultPlane
|
inPlane .= args.plane ? `, ${args.plane[0]}` : defaultPlane
|
||||||
switch method
|
switch method
|
||||||
/arc|sector/
|
/arc|sector/
|
||||||
unless args.subpoints?.length is 3 return
|
unless args.subpoints?.length is 3 return
|
||||||
@ -1012,6 +1048,7 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
center = temp
|
center = temp
|
||||||
parms = start + ', ' + center + ', ' + end
|
parms = start + ', ' + center + ', ' + end
|
||||||
prefix = 'Circumcircular'
|
prefix = 'Circumcircular'
|
||||||
|
inPlane = '' // not needed in 3-point case
|
||||||
ends[0] = start
|
ends[0] = start
|
||||||
ends[1] = end
|
ends[1] = end
|
||||||
commands.push
|
commands.push
|
||||||
@ -1029,6 +1066,10 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
'3points'
|
'3points'
|
||||||
unless args.subpoints?.length is 3 then return
|
unless args.subpoints?.length is 3 then return
|
||||||
commands.push `${name} = Plane(${args.subpoints.join ','})`
|
commands.push `${name} = Plane(${args.subpoints.join ','})`
|
||||||
|
'parallel'
|
||||||
|
unless args.subpoints?.length is 1 then return
|
||||||
|
unless args.plane?.length is 1 then return
|
||||||
|
commands.push `${name} = Plane(${args.subpoints[0]}, ${args.plane[0]})`
|
||||||
'perpendicular'
|
'perpendicular'
|
||||||
unless args.subpoints?.length is 2 then return
|
unless args.subpoints?.length is 2 then return
|
||||||
[thru, perp] := args.subpoints
|
[thru, perp] := args.subpoints
|
||||||
@ -1099,6 +1140,33 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||||||
api.renameObject obj, newObj
|
api.renameObject obj, newObj
|
||||||
moreParts[1].push newObj
|
moreParts[1].push newObj
|
||||||
ix += 1
|
ix += 1
|
||||||
|
'prism'
|
||||||
|
unless args.polygon?.length is 1 then return
|
||||||
|
base := args.polygon[0]
|
||||||
|
ends[0] = base
|
||||||
|
pt := args.subpoints
|
||||||
|
unless pt and pt.length is 2 then return
|
||||||
|
commands.push
|
||||||
|
`${aux}1 = Vertex(${base},1) + ${pt[1]} - ${pt[0]}`
|
||||||
|
auxiliaries.push aux+1
|
||||||
|
ends[1] = aux+1
|
||||||
|
parts[0].push aux+1
|
||||||
|
parts[2].push ends[0]
|
||||||
|
callbacks.push (api: AppletObject, moreParts: DimParts) =>
|
||||||
|
made := api.evalCommandGetLabels
|
||||||
|
`${name} = Prism(${base}, ${aux}1)`
|
||||||
|
if not made return
|
||||||
|
for each obj of made.split ','
|
||||||
|
if obj is name continue
|
||||||
|
newObj := 'GeoAux' + index + obj
|
||||||
|
api.renameObject obj, newObj
|
||||||
|
switch api.getObjectType newObj
|
||||||
|
'point'
|
||||||
|
moreParts[0].push newObj
|
||||||
|
'segment'
|
||||||
|
moreParts[1].push newObj
|
||||||
|
else
|
||||||
|
moreParts[2].push newObj
|
||||||
/pyramid|tetrahedron/
|
/pyramid|tetrahedron/
|
||||||
base .= args.polygon?[0]
|
base .= args.polygon?[0]
|
||||||
ends[0] = base or aux + 1
|
ends[0] = base or aux + 1
|
||||||
|
Loading…
Reference in New Issue
Block a user