feat: complete commands needed for Book Eleven
This commit is contained in:
parent
e10da118a7
commit
c903a42f89
@ -67,6 +67,7 @@ type ConstructionData
|
||||
height: number
|
||||
elements: JoyceElements
|
||||
pivot: string
|
||||
title?: string
|
||||
|
||||
// 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
|
||||
@ -186,7 +187,8 @@ type ClassHandler = (
|
||||
method: string,
|
||||
args: JoyceArguments,
|
||||
index: number,
|
||||
cdata: ConstructionData) => Commander
|
||||
cdata: ConstructionData,
|
||||
colors: string[]) => Commander
|
||||
type RGB = [number, number, number]
|
||||
type XYZ = RGB
|
||||
|
||||
@ -208,6 +210,7 @@ function dispatchJcommand(
|
||||
'title'
|
||||
if adapParams.config?.commands
|
||||
console.log 'Setting title to', value
|
||||
cdata.title = value
|
||||
api.evalCommand `TitlePoint = Corner(1,1)
|
||||
Text("${value}", TitlePoint + (2,5))`
|
||||
'pivot'
|
||||
@ -257,7 +260,7 @@ function jToG(
|
||||
args: JoyceArguments := {}
|
||||
usesCaptions := []
|
||||
for each jdep of data.split ','
|
||||
scalar := parseFloat jdep
|
||||
scalar := Number jdep
|
||||
if scalar is scalar // not NaN
|
||||
(args.scalar ?= []).push scalar
|
||||
continue
|
||||
@ -271,7 +274,7 @@ function jToG(
|
||||
(args.subpoints ?= []).push depGeo
|
||||
else if depKlass is 'line'
|
||||
(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) =>
|
||||
api.setCaption name, jname
|
||||
api.setLabelStyle name, 3 // style CAPTION = 3
|
||||
@ -517,7 +520,7 @@ function pointDefaultColorName(
|
||||
|
||||
function 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:
|
||||
if /^[A-Z]['\w]*$/.test jname then return jname
|
||||
// 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
|
||||
// function.
|
||||
classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
point: (name, method, args, index, cdata): Commander =>
|
||||
point: (name, method, args, index, cdata, colors): Commander =>
|
||||
return := freshCommander()
|
||||
{commands, callbacks, parts, auxiliaries} := return.value
|
||||
zeroVector := cdata.is3d ? 'Vector((0,0,0))' : 'Vector((0,0))'
|
||||
@ -579,6 +582,22 @@ 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
|
||||
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
|
||||
/angle(?:Bisector|Divider)/
|
||||
{center, foot} :=
|
||||
@ -608,6 +627,12 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
if args.scalar and args.scalar.length
|
||||
callbacks.push (api: AppletObject) =>
|
||||
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/
|
||||
pt := args.subpoints
|
||||
unless pt and pt.length is 4 then return
|
||||
@ -616,9 +641,9 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
commands.push `${name} = Translate(${source}, ${displacement})`
|
||||
'first'
|
||||
unless args.subpoints then return
|
||||
// HACK: Special-case correction for Joyce Elements Bk II, prop 14
|
||||
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
|
||||
commands.push `${name} = ${args.subpoints[index]}`
|
||||
/fixed|free/
|
||||
@ -642,9 +667,9 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
// Checking Joyce source, means intersection of lines, not
|
||||
// intersection of line segments
|
||||
pt := args.subpoints
|
||||
unless pt then return
|
||||
unless pt and pt.length > 1 then return
|
||||
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})`
|
||||
'last'
|
||||
unless args.subpoints then return
|
||||
@ -696,8 +721,9 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
`${name} = Rotate(${pt[1]}, pi/2, ${center}${inPlane})`
|
||||
when 3 // perpendicular **to** the plane
|
||||
// Uses lots of auxiliaries
|
||||
radius := `Distance(${pt[1]}, ${pt[2]})`
|
||||
commands.push
|
||||
`${aux}1 = Circle(${center}, Distance(${pt[1]}, ${pt[2]})${inPlane})`
|
||||
`${aux}1 = Circle(${center}, ${radius}${inPlane})`
|
||||
`${aux}2 = PointIn(${aux}1)`
|
||||
`${aux}3 = PerpendicularLine(${center}${inPlane})`
|
||||
`${aux}4 = Plane(${aux}2, ${aux}3)`
|
||||
@ -847,7 +873,17 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
commands.push
|
||||
`${aux} = Rotate(${pt[1]}, pi/2, ${pt[0]}${inPlane})`
|
||||
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
|
||||
ends[0] = pt[0]
|
||||
ends[1] = aux + 2
|
||||
@ -998,7 +1034,7 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
aux := name + 'aUx'
|
||||
parts[2].push name
|
||||
defaultPlane := cdata.is3d ? ', xOyPlane' : ''
|
||||
inPlane := args.plane ? `, ${args.plane[0]}` : defaultPlane
|
||||
inPlane .= args.plane ? `, ${args.plane[0]}` : defaultPlane
|
||||
switch method
|
||||
/arc|sector/
|
||||
unless args.subpoints?.length is 3 return
|
||||
@ -1012,6 +1048,7 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
center = temp
|
||||
parms = start + ', ' + center + ', ' + end
|
||||
prefix = 'Circumcircular'
|
||||
inPlane = '' // not needed in 3-point case
|
||||
ends[0] = start
|
||||
ends[1] = end
|
||||
commands.push
|
||||
@ -1029,6 +1066,10 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
'3points'
|
||||
unless args.subpoints?.length is 3 then return
|
||||
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'
|
||||
unless args.subpoints?.length is 2 then return
|
||||
[thru, perp] := args.subpoints
|
||||
@ -1099,6 +1140,33 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
||||
api.renameObject obj, newObj
|
||||
moreParts[1].push newObj
|
||||
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/
|
||||
base .= args.polygon?[0]
|
||||
ends[0] = base or aux + 1
|
||||
|
Loading…
Reference in New Issue
Block a user