fix: correct colors of labels when point color defaults (#51)

Also fixes motion of points when pivoting if they lie on a circle that only later has its center identified as the pivot point (i.e., not yet at the time the pivotable point is being defined).
Also implements the "center" method of constructing a point.

With this PR, apparently all diagrams through Book III work OK.

Reviewed-on: #51
Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Co-committed-by: Glen Whitney <glen@studioinfinity.org>
This commit is contained in:
Glen Whitney 2023-11-29 05:37:20 +00:00 committed by Glen Whitney
parent 6489fb7fac
commit 29dfc54646
1 changed files with 79 additions and 61 deletions

View File

@ -77,6 +77,7 @@ type PivotData
pivot: string
lastAngle: number
rotatable: string[]
maybeRotatable: Record<string, string>
fixed: Record<string, boolean>
pivotData: Record<string, PivotData> := {}
@ -112,13 +113,18 @@ function postApplets(jApplets: AppletDescription[], codebase = '')
pivot = geoname(jApp.id, elements, 'point') + 'Pivot'
pivotData[pivot] = {
api, jApp.params.pivot,
lastAngle: 0, rotatable: [], fixed: {}}
lastAngle: 0, rotatable: [], maybeRotatable: {}, fixed: {}}
cdata: ConstructionData := {
bg: ([255, 255, 255] as RGB),
is3d, jApp.id, jApp.width, jApp.height, elements, pivot}
for name, value in jApp.params
dispatchJcommand
api, name, value, cdata
if pivot
pd := pivotData[pivot]
for entity, circ in pd.maybeRotatable
if cdata.elements[circ].ends?[0] is pd.pivot
pd.rotatable.push entity
if is3d
depth .= jApp.width
if jApp.height > depth then depth = jApp.height
@ -350,8 +356,9 @@ function jToG(
console.log 'Hiding point', point if traceC
api.setVisible point, false
else if dimension is 0 or colors[1] // Need to color the points
ptRGB := colors[1] ? joyce2rgb colors[1], cdata.bg
: pointDefaultRGB name, method, isPivot
if not colors[1]
colors[1] = pointDefaultColorName name, method, isPivot
ptRGB := joyce2rgb colors[1], cdata.bg
for each point of parts[0]
console.log 'Coloring point', point, 'to', colors[1] if traceC
api.setVisible point, true
@ -361,47 +368,51 @@ function jToG(
if invisible colors[0]
console.log 'Hiding label', name if traceC
api.setLabelVisible name, false
else if colors[dimension+1] and colors[dimension+1] is not colors[0]
// Have to make a text to provide the caption, since GeoGebra
// doesn't allow caption different color from entity.
textName := 'GeoText' + index
locationExpr := switch klass
when 'point' then `1.02${name}`
when 'line'
(`Midpoint(${name}) + `
+ `Rotate(Direction(${name})*Length(${name})*0.02, pi/2)`)
when 'circle'
`Center(${name}) + Radius(${name})*Vector((12/13,5/13))*1.03`
when 'polygon' then `Centroid(${name})`
when 'sector'
`(5*Center(${name}) - ${cmdr.ends?[0]} - ${cmdr.ends?[1]})/3`
when 'plane'
`Intersect(${name}, PerpendicularLine((0, 0, 0), ${name}))`
when 'sphere'
`Center(${name})+Radius(${name})*Vector((12/13,0,5/13))*1.03`
when 'polyhedron'
// The "ends" are faces or vertices roughly opposite
// from each other
[ex1, ex2] .= cmdr.ends ?? ['', '']
unless parts[0].includes ex1 then ex1 = `Centroid(${ex1})`
unless parts[0].includes ex2 then ex2 = `Centroid(${ex2})`
`(4*${ex1}+${ex2})/5`
textCmd := `${textName} = Text("${jname}", ${locationExpr})`
textCol := joyce2rgb colors[0], cdata.bg
if traceC
console.log `Making text '${textCmd}' colored`, textCol
api.evalCommand textCmd
api.setColor textName, ...textCol
// and hide the underlying GeoGebra label
api.setLabelVisible name, false
else if colors[0]
// Label gets the correct color from element
// but we had better make sure it is visible:
console.log 'Showing label', name if traceC
api.setLabelVisible name, true
else
// label color is defaulting. Same as element for points, invisible
// otherwise:
if colors[dimension+1] and colors[dimension+1] is not colors[0]
// Have to make a text to provide the caption, since GeoGebra
// doesn't allow caption different color from entity.
textName := 'GeoText' + index
locationExpr := switch klass
when 'point' then `1.02${name}`
when 'line'
(`Midpoint(${name})`
+ ` + Rotate(Direction(${name})`
+ `*Length(${name})*0.02, pi/2)`)
when 'circle'
(`Center(${name})`
+ ` + Radius(${name})*Vector((12/13,5/13))*1.03`)
when 'polygon' then `Centroid(${name})`
when 'sector'
(`(5*Center(${name})`
+ ` - ${cmdr.ends?[0]} - ${cmdr.ends?[1]})/3`)
when 'plane'
`Intersect(${name}, PerpendicularLine((0, 0, 0), ${name}))`
when 'sphere'
(`Center(${name})`
+ ` + Radius(${name})*Vector((12/13,0,5/13))*1.03`)
when 'polyhedron'
// The "ends" are faces or vertices roughly opposite
// from each other
[ex1, ex2] .= cmdr.ends ?? ['', '']
unless parts[0].includes ex1 then ex1 = `Centroid(${ex1})`
unless parts[0].includes ex2 then ex2 = `Centroid(${ex2})`
`(4*${ex1}+${ex2})/5`
textCmd := `${textName} = Text("${jname}", ${locationExpr})`
textCol := joyce2rgb colors[0], cdata.bg
if traceC
console.log `Making text '${textCmd}' colored`, textCol
api.evalCommand textCmd
api.setColor textName, ...textCol
// and hide the underlying GeoGebra label
api.setLabelVisible name, false
else // specified label color matches the entity color
// So label gets the correct color from element
// but we had better make sure it is visible:
console.log 'Showing label', name if traceC
api.setLabelVisible name, true
else // label color is defaulting
// Make it same as the element for points, invisible otherwise:
show := klass is 'point'
console.log 'Setting label vis of', name, 'to', show if traceC
api.setLabelVisible name, show
@ -486,14 +497,15 @@ function joyce2rgb(cname: string, backgroundRGB?: RGB): RGB
console.warn 'Could not parse color:', cname
[128, 128, 128]
function pointDefaultRGB(name: string, method: string, isPivot: boolean): RGB
if isPivot then return joyce2rgb 'green'
function pointDefaultColorName(
name: string, method: string, isPivot: boolean): string
if isPivot then return 'green'
switch method
'free'
joyce2rgb 'red'
'red'
/.*[Ss]lider$/
joyce2rgb 'orange'
else joyce2rgb 'black'
'orange'
else 'black'
function geoname(
jname: JoyceName, elements: JoyceElements, klass: JoyceClass): GeoName
@ -564,14 +576,26 @@ classHandler: Record<JoyceClass, ClassHandler> :=
makeAngDiv(method, args, cdata, aux, auxiliaries, commands)
unless foot return
commands.push `${name} = ${foot}`
'center'
entity := args.circle ? args.circle[0] : args.sphere?[0]
if entity
commands.push `${name} = Center(${entity})`
entityEnds := cdata.elements[entity].ends
if entityEnds and not entityEnds[0]
entityEnds[0] = name // labeled the center
else
console.warn 'Nothing to produce center point of in',
name, method, args
'circleSlider'
unless args.circle then return
circ := args.circle[0]
commands.push `${name} = Point(${circ})`
if (pivotable
and cdata.elements[circ].ends?[0] // center
is pivotData[cdata.pivot].pivot)
pivotData[cdata.pivot].rotatable.push name
if pivotable
maybeCenter := cdata.elements[circ].ends?[0]
if maybeCenter is pivotData[cdata.pivot].pivot
pivotData[cdata.pivot].rotatable.push name
if not maybeCenter
pivotData[cdata.pivot].maybeRotatable[name] = circ
if args.scalar and args.scalar.length
callbacks.push (api: AppletObject) =>
api.setCoords name, ...vertFlipped(args.scalar or [], cdata)
@ -658,6 +682,7 @@ classHandler: Record<JoyceClass, ClassHandler> :=
'vertex'
commands.push
`${name} = Vertex(${args.polygon?[0]},${args.scalar?[0]})`
else console.warn 'Unknown point method:', method
line: (name, method, args, index, cdata) =>
return := freshCommander()
@ -770,15 +795,8 @@ classHandler: Record<JoyceClass, ClassHandler> :=
ends[0] = pt[0]
ends[1] = aux
auxiliaries.push aux
if args.line?.length is 1
ln := args.line[0]
commands.push
`${name} = Rotate(${ln}, pi/2, ${pt[0]}${inPlane})`
`${aux} = Vertex(${name}, 2)`
madeSegment = true
else
commands.push
`${aux} = Rotate(${pt[1]}, pi/2, ${pt[0]}${inPlane})`
commands.push
`${aux} = Rotate(${pt[1]}, pi/2, ${pt[0]}${inPlane})`
when 3
return // TODO: line perpendicular to plane
when 4