From 29dfc546468100d89dd3e8dc1ab65635b74f2228 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Wed, 29 Nov 2023 05:37:20 +0000 Subject: [PATCH] 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: https://code.studioinfinity.org/glen/archematics/pulls/51 Co-authored-by: Glen Whitney Co-committed-by: Glen Whitney --- src/adapptlet.civet | 140 +++++++++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/src/adapptlet.civet b/src/adapptlet.civet index aafef02..f99f39e 100644 --- a/src/adapptlet.civet +++ b/src/adapptlet.civet @@ -77,6 +77,7 @@ type PivotData pivot: string lastAngle: number rotatable: string[] + maybeRotatable: Record fixed: Record pivotData: Record := {} @@ -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 := 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 := '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 := 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