diff --git a/src/adapptlet.civet b/src/adapptlet.civet index 3046e4e..37b29ef 100644 --- a/src/adapptlet.civet +++ b/src/adapptlet.civet @@ -49,6 +49,16 @@ adapParams: AdapParams := ? {loader: 'https://www.geogebra.org/apps/deployggb.js', joyceApplets: []} : JSON.parse(adapptScript.dataset.params ?? '') as AdapParams +// For accessing/setting the y coordinate of a set of coordinates: +Y := 1 +Z := 2 +function vertFlipped(coords: number[], cdata: ConstructionData): XYZ + coords = coords.slice() + if cdata.is3d + if coords[Z] then coords[Z] = -coords[Z] + else coords[Y] = cdata.height - coords[Y] + return coords as XYZ + type ConstructionData id: string bg: RGB @@ -285,12 +295,13 @@ function jToG( api.registerObjectUpdateListener(cdata.pivot, 'pivotListener') // Create callback to assign colors + traceC := adapParams.config?.color + console.log 'Considering coloring', name, 'with', colors if traceC if colors.length is 4 and colors.every (color) => invisible color cmdr.callbacks.push (api: AppletObject) => api.setVisible name, false else // we have to decorate dimension .= cmdr.parts.findLastIndex .includes name cmdr.callbacks.push (api: AppletObject, parts: DimParts) => - trace := adapParams.config?.color // Operate in order faces, lines, point, caption so that // we can adjust components after setting overall color, etc. @@ -298,18 +309,18 @@ function jToG( if invisible colors[3] for each face of parts[2] if face is name - console.log 'Fading out interior of', face if trace + console.log 'Fading out interior of', face if traceC // hide the interior by making it transparent api.setFilling face, 0 else if face not in cdata.elements - console.log 'Hiding face', face if trace + console.log 'Hiding face', face if traceC api.setVisible face, false else faceRGB := joyce2rgb(colors[3] or 'brighter', cdata.bg) deep := ['circle', 'polygon', 'sector'] filling := deep.includes(klass) ? 0.7 : 0.2 for each face of parts[2] - console.log 'Coloring face', face, 'to', colors[3] if trace + console.log 'Coloring face', face, 'to', colors[3] if traceC api.setVisible face, true api.setFilling face, filling api.setColor face, ...faceRGB @@ -318,17 +329,17 @@ function jToG( if invisible colors[2] for each line of parts[1] if line is name or line not in cdata.elements - console.log 'Hiding line', line if trace + console.log 'Hiding line', line if traceC api.setVisible line, false else lineRGB := joyce2rgb(colors[2] or 'black', cdata.bg) for each line of parts[1] - console.log 'Coloring line', line, 'to', colors[2] if trace + console.log 'Coloring line', line, 'to', colors[2] if traceC api.setVisible line, true api.setColor line, ...lineRGB // Now color the points: - if trace + if traceC console.log 'Considering point colors for', name, 'of dimension', dimension if invisible colors[1] @@ -336,19 +347,19 @@ function jToG( // items: for each point of parts[0] if point is name or point not in cdata.elements - console.log 'Hiding point', point if trace + 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 for each point of parts[0] - console.log 'Coloring point', point, 'to', colors[1] if trace + console.log 'Coloring point', point, 'to', colors[1] if traceC api.setVisible point, true api.setColor point, ...ptRGB // Make the caption the correct color if invisible colors[0] - console.log 'Hiding label', name if trace + 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 @@ -377,7 +388,7 @@ function jToG( `(4*${ex1}+${ex2})/5` textCmd := `${textName} = Text("${jname}", ${locationExpr})` textCol := joyce2rgb colors[0], cdata.bg - if trace + if traceC console.log `Making text '${textCmd}' colored`, textCol api.evalCommand textCmd api.setColor textName, ...textCol @@ -386,13 +397,13 @@ function jToG( 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 trace + console.log 'Showing label', name if traceC api.setLabelVisible name, true else // label color is defaulting. Same as element for points, invisible // otherwise: show := klass is 'point' - console.log 'Setting label vis of', name, 'to', show if trace + console.log 'Setting label vis of', name, 'to', show if traceC api.setLabelVisible name, show cdata.elements[jname] = {otherName: name, usesCaptions, klass, cmdr.ends} @@ -563,7 +574,7 @@ classHandler: Record := pivotData[cdata.pivot].rotatable.push name if args.scalar and args.scalar.length callbacks.push (api: AppletObject) => - api.setCoords name, ...args.scalar as XYZ + api.setCoords name, ...vertFlipped(args.scalar or [], cdata) /cutoff|extend/ pt := args.subpoints unless pt and pt.length is 4 then return @@ -574,8 +585,8 @@ classHandler: Record := unless args.subpoints then return commands.push `${name} = ${args.subpoints[0]}` /fixed|free/ - coords := args.scalar - unless coords then return + unless args.scalar then return + coords := vertFlipped(args.scalar, cdata) scoord := coords.join ',' if pivotable then pivotData[cdata.pivot].rotatable.push name commands.push `${name} = (${scoord})` @@ -612,14 +623,14 @@ classHandler: Record := commands.push `${name} = Point(${segment})` if args.scalar and args.scalar.length callbacks.push (api: AppletObject) => - api.setCoords name, ...args.scalar as XYZ + api.setCoords name, ...vertFlipped(args.scalar or [], cdata) 'lineSlider' pt := args.subpoints unless pt and pt.length is 2 then return commands.push `${name} = Point(Line(${pt[0]}, ${pt[1]}))` if args.scalar and args.scalar.length callbacks.push (api: AppletObject) => - api.setCoords name, ...args.scalar as XYZ + api.setCoords name, ...vertFlipped(args.scalar or [], cdata) 'midpoint' if args.line commands.push `${name} = Midpoint(${args.line[0]})` @@ -634,8 +645,7 @@ classHandler: Record := // Note only the two-point option implemented so far unless args.subpoints return [center, direction] := args.subpoints - // Note clockwise 90° rotation (3π/2) confirmed in Joyce source - commands.push `${name} = Rotate(${direction}, 3*pi/2, ${center})` + commands.push `${name} = Rotate(${direction}, pi/2, ${center})` /proportion|similar/ [source, displacement] := proportionSimilar method, args, cdata, aux, commands, auxiliaries @@ -665,7 +675,7 @@ classHandler: Record := 'bichord' // To match Joyce, we need to get the ordering here correct. // we want the order so that start -> end sweeping past the - // center of the other circle is counterclockwise in the first + // center of the other circle is clockwise in the first // circle cr := args.circle unless cr return @@ -676,8 +686,8 @@ classHandler: Record := condition := (`Angle(${aux}1,${ctr[0]},${ctr[1]}${inPlane})` + `< Angle(${aux}2,${ctr[0]},${ctr[1]}${inPlane})`) commands.push - `${aux}3 = If(${condition}, ${aux}2, ${aux}1)` - `${aux}4 = If(${condition}, ${aux}1, ${aux}2)` + `${aux}3 = If(${condition}, ${aux}1, ${aux}2)` + `${aux}4 = If(${condition}, ${aux}2, ${aux}1)` ends[0] = aux + 3 ends[1] = aux + 4 auxiliaries.push ...[1..4].map (n) => aux + n @@ -748,12 +758,12 @@ classHandler: Record := if args.line?.length is 1 ln := args.line[0] commands.push - `${name} = Rotate(${ln}, 3*pi/2, ${pt[0]}${inPlane})` + `${name} = Rotate(${ln}, pi/2, ${pt[0]}${inPlane})` `${aux} = Vertex(${name}, 2)` madeSegment = true else commands.push - `${aux} = Rotate(${pt[1]}, 3*pi/2, ${pt[0]}${inPlane})` + `${aux} = Rotate(${pt[1]}, pi/2, ${pt[0]}${inPlane})` when 3 return // TODO: line perpendicular to plane when 4 @@ -854,7 +864,7 @@ classHandler: Record := else if method is 'application' unless pt.length is 3 then return unless args.polygon?.length is 1 then return - direction := `UnitVector(${pt[2]} - ${pt[0]})` + direction := `UnitVector(${pt[0]} - ${pt[2]})` angle := `Angle(${pt[1]},${pt[0]},${pt[2]})` length := `Area(${args.polygon})` + `/(Distance(${pt[0]},${pt[1]})*sin(${angle}))` @@ -900,12 +910,12 @@ classHandler: Record := /arc|sector/ unless args.subpoints?.length is 3 return parts[0].push ...args.subpoints - [center, end, start] .= args.subpoints + [center, start, end] .= args.subpoints parms .= center + ', ' + start + ', ' + end prefix .= 'Circular' if method is 'arc' - temp := end - end = center + temp := start + start = center center = temp parms = start + ', ' + center + ', ' + end prefix = 'Circumcircular'