From bab48b25ad04215009a96d07198abe9c5b3bc7af Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Mon, 25 Sep 2023 00:47:35 +0000 Subject: [PATCH] feat: Improve construction element handling (#32) This change implements several additional construction methods, including the first polygon ones. In particular, it now allows arbitrary strings as entity names, even ones that are not allowed as GeoGebra identifiers, using captions to show the original entity names. In addition, line arguments are interpreted as a pair of point arguments as needed. Resolves #6. Resolves #30. Resolves #31. Reviewed-on: https://code.studioinfinity.org/glen/archematics/pulls/32 Co-authored-by: Glen Whitney Co-committed-by: Glen Whitney --- public/Geometry.zip | Bin 0 -> 103571 bytes public/index.html | 1 + public/inscribed-revived.html | 135 ++++++++++++ src/adapptlet.civet | 373 ++++++++++++++++++++++++++++------ src/giveAwrl.civet | 2 +- 5 files changed, 448 insertions(+), 63 deletions(-) create mode 100644 public/Geometry.zip create mode 100644 public/inscribed-revived.html diff --git a/public/Geometry.zip b/public/Geometry.zip new file mode 100644 index 0000000000000000000000000000000000000000..9e9eaf94079b7fbf64d9ae74adcf47e1b1da3b1d GIT binary patch literal 103571 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
qJs8o=jgsb?GGf1Z#)%ZZJtCL59gkVo3(; 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 literal 0 HcmV?d00001 diff --git a/public/index.html b/public/index.html index c638339..2b5424f 100644 --- a/public/index.html +++ b/public/index.html @@ -8,6 +8,7 @@

Joyce Geometry Applet

WRL Files

diff --git a/public/inscribed-revived.html b/public/inscribed-revived.html new file mode 100644 index 0000000..9d491f5 --- /dev/null +++ b/public/inscribed-revived.html @@ -0,0 +1,135 @@ + + + + + + + +An equilateral triangle inscribed in a rectangle + + + + + + + +

An equilateral triangle inscribed in a rectangle

+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +Slide the “@” up and down to change the geometry.
+Press “r” to reset the diagram to its initial state.
+Proposition: The blue area equals the sum of the two pink areas. +
+
+ +

Problem statement

+ +

+The diagram above shows an equilateral triangle inscribed in a rectangle +in such a way that the two have a vertex in common. This subdivides the +rectangle into four disjoint triangles. +The original equilateral triangle is shown in white +in the diagram; the other three are shown in color. + +

+Proposition + +The area of the blue triangle equals the sum +of the areas of the two pink triangles. + + +

+The trigonometric proof is quite straightforward. I don't +know of a classical proof a la Euclid. +(Well, actually I haven't tried much.) +If you can think of a neat non-trigonometric proof, let me know. I will +put it here with due credit. + +

+This problem appeared as a conjecture +in an article +in the geometry.puzzles newsgroup on March 15, 1997. + +

+Note added January 8, 2017: +Here is a +clever solution +that Peter Renz sent me a in December 2016. Thanks, Peter! + +


+

+This applet was created by +Rouben Rostamian +using +David Joyce's +Geometry +Applet +on July 2, 2010. + +

+ + + + + +
Go to Geometry Problems and Puzzles + +Valid HTML + +Valid CSS +
+ + + + diff --git a/src/adapptlet.civet b/src/adapptlet.civet index 5fbc3fb..0cd01e4 100644 --- a/src/adapptlet.civet +++ b/src/adapptlet.civet @@ -16,6 +16,30 @@ $('applet[code="Geometry"]').before (i, html) -> height: parseInt(this.getAttribute('height') ?? '200') } `

` +type Split + S extends `${infer W} ${infer R}` ? (W | Split) : S + +classes := 'point line circle polygon sector plane sphere polyhedron' +type JoyceClass = Split +function assertJoyceClass(s: string): asserts s is JoyceClass + unless classes.includes s then throw new Error `Oops ${s} slipped through` + +type JoyceName = string // we use this to indicate where the names + // from the Joyce commands (which are used as captions in the GeoGebra + // applet) go. +type GeoName = string // and this to indicate where GeoGebra identifiers go +type AnyName = GeoName | JoyceName // and this for slots that can be either + +type Description + otherName: AnyName + usesCaptions: JoyceName[] + klass: JoyceClass + ends?: [GeoName, GeoName] + +// We put both JoyceNames and GeoNames in here, pointing to each other +// with the otherName property: +type JoyceElements = Record + jQuery.getScript 'https://www.geogebra.org/apps/deployggb.js', => for each jApp of joyceApplets params := { @@ -23,100 +47,325 @@ jQuery.getScript 'https://www.geogebra.org/apps/deployggb.js', => jApp.width, jApp.height, appletOnLoad: (api: AppletObject) => + elements: JoyceElements := {} for child of jApp.children - dispatchJcommand api, child + dispatchJcommand api, child, elements api.setCoordSystem(-10, 10 + jApp.width, -10, 10 + jApp.height) } as const geoApp := new GGBApplet params geoApp.inject jApp.id -type GeogebraCallback = (api: AppletObject) => void +type DimParts = [string[], string[], string[]] // Gives GeoNames + // or expressions for 0-, 1-, and 2-dimensional parts for coloring + +// need to pass the parts into the callbacks because sometimes the parts +// are not generated until callback time +type GeogebraCallback = (api: AppletObject, parts: DimParts) => void type Commander - command: string + commands: string[] callbacks: GeogebraCallback[] + parts: DimParts + auxiliaries: GeoName[] // extra entities needed in GeoGebra + ends?: [GeoName, GeoName] + +function freshCommander(): Commander + commands: [] + callbacks: [] + parts: [[], [], []] + auxiliaries: [] + +type JoyceArguments = + Partial & {scalar: number[]}> type ClassHandler = ( - name: string, m: string, data: string, colors: string[]) => Commander + name: GeoName, m: string, args: JoyceArguments, index: number) => Commander -function dispatchJcommand(api: AppletObject, param: Element): void +// Executes the command corresponding to param against the GeoGebra applet +// api, consulting and extending by side effect the elements that are +// present in that applet +function dispatchJcommand( + api: AppletObject, param: Element, elements: JoyceElements): void val := param.getAttribute 'value' unless val return - switch param.getAttribute 'name' + attr := param.getAttribute 'name' + switch attr 'background' api.setGraphicsOptions 1, bgColor: `#${val}` 'title' api.evalCommand `TitlePoint = Corner(1,1) Text("${val}", TitlePoint + (2,5))` /e\[\d+\]/ - {command, callbacks} := jToG val - if command - if api.evalCommand command - for each cb of callbacks - cb(api) - else - console.log `Geogebra command '${command}' translated from`, - val, 'failed.' - else - console.log `Could not parse command '${val}'` - else - console.log `Unkown param ${param}` + num := parseInt(attr.slice(2)) + {commands, callbacks, parts} := jToG val, elements, num + if commands.length + lastTried .= 0 + if commands.filter((&)).every (cmd) => + api.evalCommand(cmd) and ++lastTried + callbacks.forEach &(api, parts) + else console.log + `Geogebra command '${commands[lastTried]}' + (part of translation of '${val}') + failed.` + else console.log `Could not parse command '${val}'` + else console.log `Unkown param ${param}` -function jToG(jCom: string): Commander - [name, klass, method, data, ...colors] := jCom.split(';') - if klass in classHandler - return classHandler[klass] name, method, data, colors - console.log `Unknown entity class ${klass}` - command: '', callbacks: [] +// function myListener(...args: unknown[]) { +// console.log 'In my listener with', args +// } -classHandler: Record := - point: (name, method, data, colors) => - command .= '' - callbacks: GeogebraCallback[] .= [] - args := data.split(',') +// window.myListener = myListener + +// Parses a Joyce element-creating command, extending the elements +// by side effect: +function jToG(jCom: string, elements: JoyceElements, index: number): Commander + [jname, klass, method, data, ...colors] := jCom.split(';') + cmdr .= freshCommander() + unless klass in classHandler + console.log `Unknown entity class ${klass}` + return cmdr + assertJoyceClass klass // shouldn't need to do that :-/ + name := if /^\p{L}\w*$/u.test jname then jname else geoname jname, elements + args: JoyceArguments := {} + usesCaptions := [] + for each jdep of data.split ',' + scalar := parseFloat jdep + if scalar is scalar // not NaN + (args.scalar ?= []).push scalar + continue + unless jdep in elements + console.log `Reference to unknown geometric entity ${jdep} in $jCom}` + return cmdr + usesCaptions.push jdep + {klass: depKlass, otherName: depGeo, ends} := elements[jdep] + (args[depKlass] ?= []).push depGeo + if depKlass is 'point' + (args.subpoints ?= []).push depGeo + else if depKlass is 'line' + (args.subpoints ?= []).push ...ends ?? [] + cmdr = classHandler[klass] name, method, args, index + unless name is jname then cmdr.callbacks.push (api: AppletObject) => + api.setCaption(name, jname) + api.setLabelStyle(name, 3) // style CAPTION = 3 + if cmdr.auxiliaries.length + cmdr.callbacks.push (api: AppletObject) => + for each aux of cmdr.auxiliaries + api.setAuxiliary(aux, true) + api.setVisible(aux,false) + // Create callback to assign colors + if colors.length is 4 and colors.every (color) => + false and color is '0' or color is 'none' + cmdr.callbacks.push (api: AppletObject) => + api.setVisible(name, false) +// window[hideListener] = (arg) => +// console.log('Hello', arg, 'disappearing', name) +// api.setVisible(name, false) + api.registerObjectUpdateListener(name, hideListener) + if cmdr.ends or klass is 'line' + elements[jname] = + {otherName: name, usesCaptions, klass: 'line', cmdr.ends} + elements[name] = + {otherName: jname, usesCaptions, klass: 'line', cmdr.ends} + else // any other geometry + elements[jname] = {otherName: name, usesCaptions, klass} + elements[name] = {otherName: jname, usesCaptions, klass} + cmdr + +function geoname(jname: JoyceName, elements: JoyceElements): GeoName + numCode .= 0n + numCode = numCode*128n + BigInt ch.codePointAt(0) ?? 1 for each ch of jname + return .= 'Geo' + numCode.toString(36); + return += '1' while return.value in elements + +// All of the detailed semantics of each available command lies in this +// function. +classHandler: Record := + point: (name, method, args): Commander => + return := freshCommander() + {commands, callbacks, parts, auxiliaries} := return.value + aux := name + 'aUx' + parts[0].push name switch method /free|fixed/ - command += `${name} = (${data})` + commands.push `${name} = (${args.scalar?.join ','})` if method is 'fixed' callbacks.push (api: AppletObject) => api.setFixed(name, true) 'perpendicular' - [center, direction] := args - command += `${name} = Rotate(${direction}, 3*pi/2, ${center})` + // 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})` 'angleDivider' - n .= -1 - // use the fact that NaN doesn't equal itself: - nLoc := args.findIndex((arg) => (n = parseInt arg) is n) - if n >= 0 - args.splice(nLoc) - [center, start, end] := args - command += `${name}aUx1 = Segment(${start}, ${end}) - ${name}aUx2 = Angle(${start}, ${center}, ${end}) - ${name}aUx2a = If(${name}aUx2 > pi, ${name}aUx2 - 2*pi, ${name}aUx2) - ${name}aUx3 = Rotate(${start}, ${name}aUx2a/${n}, ${center}) - ${name}aUx4 = Ray(${center}, ${name}aUx3) - ${name} = Intersect(${name}aUx1, ${name}aUx4)` + // Note doesn't yet handle plane argument + unless args.subpoints return + [start, center, end] := args.subpoints + // see if we need to make the destination segment from start to end + destination .= '' + unless args.line?.length is 1 and args.point?[0] is center + destination = aux + '1' + auxiliaries.push destination + commands.push `${destination} = Segment(${start}, ${end})` + else destination = args.line[0] + n := args.scalar?[0] + commands.push + `${aux}2 = Angle(${start}, ${center}, ${end})` + `${aux}3 = If(${aux}2 > pi, ${aux}2 - 2*pi, ${aux}2)` + `${aux}4 = Rotate(${start}, ${aux}3/${n}, ${center})` + `${name} = Intersect(${destination}, Ray(${center}, ${aux}4))` + auxiliaries.push ...[2..4].map (i) => `${aux}${i}` 'intersection' - command += `${name} = Intersect(${data})` - return {command, callbacks} + // Checking Joyce source, means intersection of lines, not + // intersection of line segments + unless args.subpoints then return + l1 := `Line(${args.subpoints[0]},${args.subpoints[1]})` + l2 := `Line(${args.subpoints[2]},${args.subpoints[3]})` + commands.push `${name} = Intersect(${l1},${l2})` + 'lineSegmentSlider' + segment .= args.line?[0] + unless segment + unless args.point then return + commands.push `${aux} = Segment(${args.point.join ','})` + auxiliaries.push aux + segment = aux + commands.push `${name} = Point(${segment})` + if args.scalar and args.scalar.length + callbacks.push (api: AppletObject) => + api.setCoords name, + ...args.scalar as [number, number, number] + 'first' + unless args.subpoints then return + commands.push `${name} = ${args.subpoints[0]}` + 'last' + unless args.subpoints then return + commands.push `${name} = ${args.subpoints.at(-1)}` + 'extend' + unless args.subpoints then return + sp := args.subpoints + direction .= `UnitVector(Vector(${sp[0]},${sp[1]}))` + if args.line and ( + not args.point or args.point[0] !== args.subpoints[0]) + direction = `UnitVector(${args.line[0]})` + displacement := `Distance(${sp[2]}, ${sp[3]})*${direction}` + commands.push `${name} = Translate(${sp[1]}, ${displacement})` + 'vertex' + commands.push + `${name} = Vertex(${args.polygon?[0]},${args.scalar?[0]})` + 'midpoint' + if args.line + commands.push `${name} = Midpoint(${args.line[0]})` + else + commands.push + `${name} = Midpoint(${args.point?[0]},${args.point?[1]})` + 'foot' + pt := args.subpoints + unless pt then return + commands.push + `${name} = ClosestPoint(Line(${pt[1]},${pt[2]}), ${pt[0]})` - line: (name, method, data, colors) => - command .= '' - callbacks: GeogebraCallback[] .= [] - args := data.split(',') + line: (name, method, args) => + return := freshCommander() + return.value.ends = ['', ''] + {commands, callbacks, parts, auxiliaries, ends} := return.value + aux := name + 'aUx' + parts[1].push name + madeSegment .= false switch method 'connect' - command += `${name} = Segment(${data})` + unless args.subpoints and args.subpoints.length is 2 then return + ends[0] = args.subpoints[0] + ends[1] = args.subpoints[1] 'parallel' - [newStart, oldStart, oldEnd] := args - command += `${name}aUx1 = Vector(${oldStart}, ${newStart}) - ${name}aUx2 = Translate(${oldEnd}, ${name}aUx1) - ${name} = Segment(${newStart}, ${name}aUx2)` - return {command, callbacks} + unless args.subpoints then return + [newStart, oldStart, oldEnd] := args.subpoints + commands.push `${aux}1 = Vector(${oldStart}, ${newStart})` + auxiliaries.push aux + 1, aux + 2 + ends[0] = newStart + ends[1] = aux + 2 + if args.line?.length is 1 and args.point?[0] is args.subpoints[0] + // In this case we are translating an existing segment + commands.push + `${name} = Translate(${args.line[0]}, ${aux}1)` + `${aux}2 = Vertex(${name}, 2)` + madeSegment = true + else + commands.push `${aux}2 = Translate(${oldEnd}, ${aux}1)` + 'chord' + // To match Joyce, we need to get the ordering here correct. + // ends[0] should be the one closer to args.subpoints[0] + unless args.subpoints and args.circle then return + line := `Line(${args.subpoints.join ','})` + pt := args.subpoints[0] + commands.push ...[1..2].map (n) => + `${aux}${n} = Intersect(${args.circle}, ${line}, ${n})` + condition := `Distance(${aux}2,${pt}) < Distance(${aux}1,${pt})` + // NOTE: Joyce's code has special case for when pt is almost + // at midpoint of chord; in that case, it starts at endpoint + // closer to the second subpoint... postponing that nicety + commands.push + `${aux}3 = If(${condition}, ${aux}2, ${aux}1)` + `${aux}4 = If(${condition}, ${aux}1, ${aux}2)` + ends[0] = aux + 3 + ends[1] = aux + 4 + auxiliaries.push ...[1..4].map (n) => aux + n + unless madeSegment + commands.push `${name} = Segment(${ends[0]},${ends[1]})` + callbacks.push (api: AppletObject) => + api.setLabelVisible(name, true) + parts[0].push ...ends - circle: (name, method, data, colors) => - command .= '' - callbacks: GeogebraCallback[] .= [] + circle: (name, method, args) => + return := freshCommander() + {commands, callbacks, parts, auxiliaries} := return.value + parts[2].push name + parts[1].push name switch method 'radius' - [center, point] := data.split(',') - command += `${name} = Circle(${center}, ${point})` - return {command, callbacks} + unless args.subpoints then return + [center, point] := args.subpoints + commands.push `${name} = Circle(${center}, ${point})` + callbacks.push (api: AppletObject) => api.setLabelVisible(name, true) + + polygon: (name, method, args, index) => + return := freshCommander() + {commands, callbacks, parts, auxiliaries} := return.value + parts[2].push name + // what to push for edges? + switch method + 'equilateralTriangle' + pt := args.subpoints + unless pt then return + commands.push '' // hack, make sure there is a command + parts[0].push pt[0], pt[1] + callbacks.push (api: AppletObject, moreParts: DimParts) => + made:= api.evalCommandGetLabels + `${name} = Polygon(${pt[1]},${pt[0]}, 3)` + 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 + 'segment' + parts[1].push newObj + 'point' + parts[0].push newObj + api.setVisible(newObj, false) + /triangle|quadrilateral/ + pt := args.subpoints + unless pt then return + commands.push '' + parts[0].push ...pt + callbacks.push (api: AppletObject, moreParts: DimParts) => + made := api.evalCommandGetLabels + `${name} = Polygon(${pt.join ','})` + if not made return + for each obj of made.split ',' + if obj is name continue + newObj := 'GeoAux' + index + obj + api.renameObject obj, newObj + parts[1].push newObj + + sector: (name, method, args) => freshCommander() + plane: (name, method, args) => freshCommander() + sphere: (name, method, args) => freshCommander() + polyhedron: (name, method, args) => freshCommander() diff --git a/src/giveAwrl.civet b/src/giveAwrl.civet index 8799121..76ff036 100644 --- a/src/giveAwrl.civet +++ b/src/giveAwrl.civet @@ -47,7 +47,7 @@ function makeBrowser(url: string) canvas // Put eye icons after all of the eligible links -links := $('a').filter -> !!@.getAttribute('href')?.match knownExtensions +links := $('a').filter -> knownExtensions.test @.getAttribute('href') ?? '' links.after -> newSpan := $('👁') newSpan.hover