Git Product home page Git Product logo

desthree's Introduction

desthree's People

Contributors

jared-hughes avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

desthree's Issues

Add geometries that take a path as input

  • Extrude; maybe name "Extrusion"
  • Shape
  • Lathe aka "Revolve"
    • always revolves about y-axis.

Extrusion and Shape take a 2-d Path as input. This could simple be a list of line segments, but it could also support Quadratic curves and Cubic Bezier curves. Simplest option would be to use splineThru to get a smooth cubic spline through the list of points.

Note: Desmos points are not currently exposed in the API, so this would require a 2d point function similar to Vector3.

Lathe takes a list of points for some reason and does not support paths.

Allow styling geometries with different materials

This would be a variation on the Mesh function that supports styling a single geometry with a list of materials instead of broadcasting over the material argument.

It appears that https://threejs.org/docs/#api/en/core/BufferGeometry.addGroup exposes this natively.

Since all other geometries (box, sphere, etc.) are subclasses of BufferGeometry, this could apply to all geometries in DesThree.

Sample use case: styling a corner of a Rubik's cube with four different colors and using a BoxGeometry for it.

Add final simple geometries

These are the last three geometries that take only numbers as argument:

Should be a relatively simple, mostly cut-paste action in geometries.js.

Styling DesThree expressions through DOM editing is not effective

A few issues here that are related:

  1. (reported by @wompking) expressions that go out the top/bottom of the screen are removed in the DOM and do not get the custom DesThree styling (cube on the left "@3" characters removed. For example, try scrolling down on https://www.desmos.com/calculator/kwroojtkoq (especially on a shorter screen)
  2. Ctrl+A on an expression adds "@3" to the end (rather, DesThree doesn't remove the "@3" because there is no graphChanged event); purely visual. For example, try pressing ctrl+A in expression 2 of https://www.desmos.com/calculator/ghjdxovcyj
  3. Collapsed folders (#21). This might not be related because it affects functionality and not visuals.

Two possible fixes to consider:

  • use CSS selectors like [expr-id=24] > ... to control style. This would be convenient, but it has the downside of not updating autoOperatorNames
  • use a MutationObserver on the expressions list to observe when expressions are changed, then check if the data property expr-id falls within the set of DesThree expressions

I'm leaning toward the second because it might fix #9 too.

Add version check

To prevent confusion between different versions of DesThree and related graphs, store the DesThree version somewhere in the state.

For 1.0+ release, include automatic migration to higher versions.

For now (0.x.x releases), just warn user that version is incorrect. Say "loaded graph will probably will not work" if minor versions differ. Give a milder warning if only patch versions differ. Include a link to https://github.com/jared-hughes/DesThree/releases/ (the correct release if possible).

If possible, give an extra warning in the save menu (if duplicate graph is unchecked) to avoid overwriting old graphs.

Can't type PointLight because it contains "int"

When trying to type "PointLight," the "int" gets converted to an integral in MathQuill. The current workaround is to copy-paste the function name from elsewhere.

I see a few ways of proceeding:

  1. rename the function to not have this conflict
  2. disable integrals in DesThree expressions
  3. replace "Po\\intL" with "PointL" in graphChanged

The third approach will probably work the best as it allows integrals inside arguments.

Add textures

This would be epic if this works.
I see two ways to load textures:

  • load the Desmos canvas into a CanvasTexture. This would allow a maximum of one texture this way unless more Desmos windows are created.
  • Load images from the Desmos image capability. These are accessible as data URIs in the expressions list, and TextureLoader supports data URIs, so this is a perfect fit.

Increase default mesh sizes

By default SphereGeometry (and others like Cone, Torus, etc.) is not smooth enough for most people's standards.

I propose a function DefaultSmooth(n) (or a variable might work better with implementation and dependencies) as a graph configuration setting to allow users to consider the tradeoff with speed. This should multiply values like widthSegments by n when not given. The value n=1 could be the current low-poly number of segments, and n=4 should be the default. Most people would not want to exceed far past n=30 (which has 900 times the number of triangle faces) for speed concerns.

Also, a TorusKnotGeometry with high p or q (maybe lcm(p,q) determines this?) should have many more tubular segments.

Function name shortening

Expressions get too long, too quickly. Changing functions like ColorRGB to RGB, IcosahedronGeometryIcosahedron, MeshBasicMaterialBasicMaterial, etc. would improve this situation.

This should happen soon to allow for better backwards compatibility.

Add parametric geometries

  • ParametricGeometry: takes (u,v) ∊ [0,1]² and returns a Vector3
  • TubeGeometry: extrudes circle along 3D curve, which takes t ∊ [0,1] and returns a Vector3.

The difficulty here is in taking Desmos functions as arguments to DesThree functions.

The global Calc object does expose the generated functions (to some degree). For example, in https://www.desmos.com/calculator/l0dcnucrrh (with the expression f(x)=x^2), Calc.controller.grapher.graphSketches[3].branches[0].compiled.fn(5) returns 5^2=25.

Perhaps values can be interpolated between generated segments from Calc.controller.grapher.graphSketches[3].branches[0].segments.

Add line and point displays

EdgesGeometry (renders all edges: includes diagonals on a BoxGeometry)
WireframeGeometry (renders only edges on faces with different normals: excludes diagonals on a BoxGeometry)

This would be a large task because these are handled differently than meshes:

  • use THREE.LineSegments instead of THREE.Mesh
  • use LineBasicMaterial or LineDashedMaterial instead of the existing mesh materials.

Points

  • use THREE.Points instead of THREE.Mesh
  • use PointsMaterial instead of the existing mesh materials.

Use Gifsmos with DesThree

Suggested by Idealistic Introvert in the Discord. This would be helpful for showcases and possibly for documentation similar to #55. A limited version could even possibly be used for tests to verify that produced visuals are consistent across versions.

Unfortunately Gifsmos does not expose its calculator object, so modification through userscript would not be simple.

Either:

  • make a PR on Gifsmos with support for using the canvas instead of calculator.asyncScreenshot
  • re-make critical parts of Gifsmos (snapshot button, frames from slider, and export frames) making use of the DesThree canvas

I would prefer going with the first option after the DesThree 1.0 release so that this is a stable project to point to.

Unify prefixes

DesThree sometimes uses @3, sometimes desThree-, sometimes three-, with no semantic difference. Should unify it all as desThree while still allowing @3 or three to be typed to insert a DesThree expression.

Function names are italicized on graph load

The autoOperatorNames property is set to include the DesThree custom expressions only after the first graph load, so function names are not italicized at first. See https://www.desmos.com/calculator/pdhfz3bq07 — expect Show, Mesh, and BoxGeometry to be in the upright font. Simply deleting and retyping the last letter of each function is an annoying workaround.

Unfortunately the latex and graph state does not save \operatorname commands.

The "add expression" icon dissapears after an "edit list" toggle

The three expression type in the add expression context menu stops showing up after toggling the edit list feature in Desmos once.

I went ahead and inspected elements and it seems the element referenced here:

const targetNode = document.querySelector('.dcg-add-expression-container')

for the MutationOverserver to keep track of the context menu gets removed/replaced by Desmos backend.

Maybe a slight modification to the observer could fix the issue. However, do note that this replacement/removal of nodes happens up to three parents above the element previously referenced when hiding and showing the expression panel. This means the safest option would be to track .dcg-exppanel-container with a following query to make sure the context menu has appeared.

Split DesThree.js

Having nearly half the program's code in one file is not great.

DesThree.js should be split into separate files for Model, View, Controller, and parser.

Unnecessary rerenders

This is a major performance issue. Something is wrong with dependency management, so many more renders are executed than necessary. Try changing the W variable in https://www.desmos.com/calculator/hhvvj3zyat — that should be fast, but the model is rerendered 75 (?) times instead of 1.

The cause is likely that rerender() is called every time each element of each list is changed.

A few remedy ideas:

  1. Throttle rerenders with requestAnimationFrame or a timer-based system akin to lodash's throttle function. This would be simple but has issues with ensuring the last update of a batch is always included
  2. Only rerender once after a shown list changes, instead of once per element. This should be done in addition to any other changes
  3. Limit rerenderings to once per graphChanged call. This would reduce the number of startup renders but have no effect on HelperExpression changes
  4. Limit rerenderings to once per HelperExpression value change. This would help if multiple arguments (in one function or spread across several) are linked to a single helper expression, but oftentimes (like in camera spherical coordinates), the Desmos variable affects several helper expressions.

I will likely not go with option 4 since it doesn't seem worth the effort. Option 1 might conceal the effects of improperly implementing the other options, so I'll implement it last.

Allow 3D clickable objects

This would use the Raycaster from three.js and a click handler.

Might want to hold off on this until clickable objects are officially released in vanilla Desmos, but that could be a year or two.

Calc.setState() doesn't seem to update helper expressions

Current test cases 11 ("All passthrough geometries") and 12 ("All materials") use the same variables and definitions for the camera position. When the test runner calls Calc.setState() to switch between them, the camera position does not update. My hunch is that the helper expressions do not update, especially because those sliders become unresponsive.

The code is getting a little out of hand

Honestly, I never expected to get this far in the project.

Obviously a single 1200+ line userscript file will not be sustainable.

Also, @SlimRunner mentioned that syntax highlighting and cold folding are not quite working in Atom.

It's time to set up a build system and ESLint.

Add orthographic camera

Who would use this? I have no idea.

Can define left/right/top/bottom same as Desmos's graphpaperBounds.mathCoordinates

Add BufferGeometry

Buffer geometry takes a list of points in 3D, along with face normals.

The face normals could be calculated like in dcaeb54, or they could be a second argument.

I'm thinking the best way to implement this is to create a Face(Vector3, Vector3, Vector3) function, and take a list of faces as argument to BufferGeometry function.

This would require rewrite of many parts of FunctionApplicationList to allow for a custom type that does not automatically broadcast over each element of the argument's list.

Remove the need for `Show`

Automatically Show geometries, meshes, and lights that are not assigned to a variable, e.g. treat AmbientLight(0.2) (which seems like it would add a light, but doesn't) as Show(AmbientLight(0.2)). Leave the behavior of light1 = AmbientLight(0.2) unchanged.

Sample changes:

Before  After
Show(AmbientLight(0.2))  AmbientLight(0.2)
Show(Mesh(Sphere(0.5)))  Sphere(0.5)
Show(Mesh(Sphere(0.5), MeshLambertMaterial()))  Mesh(Sphere(0.5), MeshLambertMaterial())

Move camera and fog options to top-right settings box

The current state of specifying camera (and soon fog & grid lines) in separate expressions has a few disadvantages:

  • multiple can exist in one graph with the potential to effect confusion
  • this doesn't make sense from a semantic standpoint
  • the existing 2D options (e.g. graphpaper bounds in math coordinates) still exist

It would make much more sense to put these options in to replace the 2D options. Backend could be similar to existing approach.

Allow for lists of objects defined with different constructors

Sample use case: making a barbell with two spheres and a cylinder. The user would want to make a list with these three objects, then use all three in a Mesh call to share the material.

Suggested syntax: geoms = [SphereGeometry(2), CylinderGeometry(1, 5), SphereGeometry(2)]

(Unfortunately, position can only be specified right now on Meshes)

Also a use case: colors = [RGB(0,0,0), RGB(100,100,100), RGB(250,250,250)] instead of colors = RGB([0,100,250], [0,100,250], [0,100,250])

This would also be a prerequisite before creating a Group function.

Show expression values in the expression result area

In vanilla Desmos, various expressions' results are shown in a preview in the expressions list (https://www.desmos.com/calculator/ufiwm7unbp).

This could be useful to implement for some DesThree types. Example path:

  • Position the camera using spherical coordinates as such: PerspectiveCamera((Rcos(a)cos(b), Rsin(b), Rsin(a)cos(b))
  • Wonder: what are the Cartesian coordinates of the camera?
  • Copy-paste the x, y, and z expressions into separate Desmos expressions
  • Graph is no longer DRY, and this is more work

It would be helpful to see the three coordinates in the expressions list.

Allow Drag Controls

It's annoying to control the view with a pair of sliders. Makes more sense to use something like OrbitControls to drag directly on the canvas.

Could be tricky to implement because view can also be controlled from PerspectiveCamera.

A few ideas:

  1. Use Desmos Regression to back-compute PerspectiveCamera arguments from the OrbitControls values. This is super complicated for little gain, and there could even be race conditions if view is controlled by a slider that is playing.
  2. Override PerspectiveCamera values with the OrbitControls values
  3. Use a function OrbitCamera that allows specifying fov, near, and far, avoiding the need for all this mess.

Put @3 prefix in expression id instead of latex

This is a very simple solution to many problems.

  • no more need to monitor the DOM and hide the '@3' elements
  • no more chance for users to accidentally select or delete the '@3' characters.
  • simplifies a few other things

Main difficulty with this would be changing the expression id in place without (a) moving the expression or (b) recalculating everything. setExpression would not work because that keeps id constant. Could probably just remove the expression then tap into Calc.controller pretty easily to dispatch a new expression event.

Alternatively, use some other property of expressions (like colorLatex or pointOpacity or something else that supports arbitrary strings) to store all metadata, including being a DesThree expression.

Add other transformations besides Position

We currently have the Position function to move meshes around, but Object3D supports so much more, main ones being rotation and scale.

I envision the following four additional functions:

  • Rotate(object3d, rotateX, rotateY, rotateZ) — difficult for users bc EulerAngles
  • RotateQuaternion(object3d, quaternion) — need to implement quaternion function. Maybe save for later.
  • LookAt(object3d, vector3) — parents of object3d must be uniformly-scaled
  • Scale(object3d, scaleX, scaleY, scaleZ) — default scaleY and scaleZ to be same as scaleX.

Currently, we clone the object for each Position call, which would cause 4× memory usage (and increased CPU usage) if an object is positioned, rotated, and scaled. Before implementing this, should restrict each object to only one Position call, only one Rotate call, etc., and implement a Group function that can create a new local axis system to reset this restriction.

Graph gradually slows down

Observe on https://www.desmos.com/calculator/p5kkfjzxr7. After using the graph for a few minutes, it seems to slow down a ton.

Can probably determine the cause in development mode. Most likely, the graph is rerendered several times or an object is re-created several times when a single variable changes.

I can't reproduce this very quickly though.

Add testing

Shouldn't be too difficult — can fetch a list of graph states to test from URLs like http://saved-work.desmos.com/calc-states/production/znvwjvv8wg from the README then call Calc.setState(state) on each. Generate test rig code that can be pasted into the browser console or maybe load desmos.com in an iframe.

Main desire would be to get 100% line coverage from tests. A few days back, I pushed a commit that accidentally renamed Dodecahedron to Dodeahedron; that would be caught by a test that covers the DodecahedronGeometry class by drawing a dodecahedron.

Include pictures in the README

These could serve two purposes:

  • let people see what DesThree graphs look like before installing the userscript
  • improve quality of usage examples

This would involve uploading screenshots (and videos?) to a /docs directory and linking those from the markdown files.

Allow text labels

This will be hard to figure out.

TextGeometry exists, as does Sprite (always faces towards the camera). These seem overcomplicated though.

Might be able to make use of Desmos's existing label functionality or just draw text on the canvas without three.js or Desmos's help.

Rerender throttling

I think I figured out how to implement re-render throttling without having the issue mentioned in #27:

  • Instead of Show and Camera functions directly re-rendering, let them mark a variable to state that the scene/camera changed
  • Loop re-renders using requestAnimationFrame()
  • Only re-render if the above variable is marked.

This would help with performance on first graph load and a few other cases, but is not especially critical.

Update documentation with new objects before 0.5.2 release

Lots of new objects and other changes recently.

I already added tests for #37, #21, and #24, but still need to add tests for:

  • new lights. I imagine a grid of objects (cubes or spheres) above a flat plane with point lights, spot lights, other lights spread about
  • fog
  • Path geometries
  • Buffer geometries

All of the above need documentation added. While doing this, consider if order of arguments make sense. E.g. lights should really have position/direction before color because color is white most of the time.

Show warnings in tooltips

Currently, warnings are logged only to the console. For example, https://www.desmos.com/calculator/v22cbxnv7v logs "ParseError: too many arguments in call to BoxGeometry." Hovering over the yellow warning sign gives the tooltip "Sorry, I don't understand the @ symbol."

Expected behavior: tooltip says "ParseError: too many arguments in call to BoxGeometry" and no need for the console log.

Add text geometry

TextGeometry

This would require modifying the parser to allow strings like "buckets"

Would probably want to keep it simple and only allow Arial font, same as vanilla Desmos.

Add a simple way to get coordinate axes

Seems like there should be some easy way to draw coordinate axes and the x-y plane. ArrowHelper with a text sprite and GridHelper should be able to help.

  1. Syntax for toggling this on/off?
  2. Should these scale with the camera zoom or always be a fixed size?

One solution would be to use a single function to answer both of these questions for each component: SetArrowScale(Num s) (and analogous SetGridScale) could toggle off display if s ≤ 0.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.