Skip to content

Releases: That-One-Nerd/Graphing

Graphing 1.3.0

03 May 13:15
ea60865
Compare
Choose a tag to compare

Here's another graphing calculator update. I know it's been a while, sorry about that. There have been a lot of new features and improvements. Here's what's new:

Of course, there are some new graphables! There's a small one, the EquationDifference graphable. This one is made to display the difference between two given equations. Nothing huge. There's also the ParametricEquation graphable, which is self explanatory. It lets you graph parametric equations. The code right now is not particularly optimized, but that's alright for now. It takes in a range for t, and two delegate methods, one for x with time and one for y with time.

I've replaced the original system for some UI elements. Things like the integrating and deriving buttons would require the graphable to be an equation specifically. That kind of limits things and prevents it from being as homebrew-able as possible. So that's been replaced. I've instead added interfaces for each of this things. So if you want your graphable to be able to be integrated, just implement the IIntegrable interface. Same for the IDerivable interface. There are also now more UI options. Converting an equation to its slope field is possible, and there's an interface for that: IConvertSlopeField, as well as some others: IConvertEquation and IConvertColumnTable. Each of those conversion interfaces come with a boolean like UngraphWhenConvertedTo[...] which specify whether the original graphable should remain graphed once converted. So like when you convert an equation to its slope field, you probably still want the equation there. But if you wanted to convert an equation difference to an equation itself, you probably don't want the original line.

We're almost done with interfaces. One more UI element that's been added is the ability to shift a graphable along the X and Y axes in the UI. It's under the "Operations" tab, and it can be controlled again with interfaces. You don't need to implement functionality for both the X and Y axes at the same time if your graphable doesn't support that (for example, a tangent line). You can instead just implement the X and Y interfaces. For X, implement the ITranslatableX, ITranslatableY for Y, and ITranslatableXY as a shorthand for both.

Speaking of UI elements, there are some new ones. Slope fields can now have their detail modified outside of the code. It's under the "Elements > Detail" tab. This one has no interface; you must be a slope field to be added to that list. This one is a bit too specific to abstract away, though there comes another graphable that can have its detail modified in some way, it'll also probably be added to that tab, only it'll invoke a different UI form. There's also the zoom form. This one already existed for a bit but has been completely revamped. The graph now supports non-square zoom levels, so things like a box zoom have been added. There's also the "Match Aspect" button, which stretches the graph window to make the zoom square. Then there's "Normalize," which zooms in/out until one of the axes is set to the default zoom. And lastly there's the ability to reset the zoom, which also resets the window zoom level. If you want to modify the exact endpoints for the window, that's also an option, and you can lock the viewport to prevent dragging, scaling, or resetting. A lot of talk for "I made the zoom system better."

There's also an update checker now! It doesn't do much at the moment, it's pretty limited as this package is just a library. I don't have the ability to replace the graphing DLL while the application is running, and then I'd have to recompile and breaking changes could screw that up. So it is just a simple popup on the bottom right of the graph form that takes you to the GitHub release if you click it. You won't be able to see it until the next release, obviously, but it's there.

One more big thing. The graphable selection system has changed. This is a fairly breaking change but not something difficult to adapt. Rather than returning a specific selected point when asked, you return a collection of more graph parts. So for example, you can have custom selection text messages (like displaying the slope rather than the point coordinates) or have additional UI elements if need be.

Anyway, that's all for now. I don't think I missed anything here? Again, sorry for the wait, see you in 1.4!


And here's the exact changelog, as usual.

  • Added an .Abstract namespace with the following interfaces:
    • IConvertColumnTable: Allows the graphable to convert to a column table. Appears in the UI under "Convert > Column Table"
    • IConvertEquation: Allows the graphable to convert to an equation. Appears in the UI under "Convert > Equation"
    • IConvertSlopeField: Allows the graphable to convert to a slope field. Appears in the UI under "Convert > Slope Field"
    • ITranslatable: Marks the graphable as shiftable. Does nothing on its own.
    • ITranslatableX: Marks the graphable as shiftable along the X-axis. Appears in the UI under "Operations > Translate"
    • ITranslatableY: Marks the graphable as shiftable along the Y-axis. Appears in the UI under "Operations > Translate"
    • ITranslatableXY: A shorthand for implementing both ITranslatableX and ITranslatableY. Both shifting UIs are accessed in the same place.
  • Added the following static readonly color properties to the GraphForm:
    • BackgroundColor: Controls the background color of the form. Currently pure white.
    • ZoomBoxColor: Controls the color of the zoom-box rectangle. Currently pure black.
    • MajorUpdateColor: Controls the text color of the update popup when the latest release is a major release above of the current version. Currently set to a red tone (#F74434).
    • MajorUpdateColor: Controls the text color of the update popup when the latest release is only a minor release above of the current version. Currently set to a orangish-gold tone (#FCA103).
  • Made the zooming system allow for rectangular zooming. The X and Y zoom levels can be changed independently.
  • Got rid of the segment check in the zooming mechanism since the zoom box mechanism can break it a bit.
  • Changed the icon of the reset viewport button.
  • Added a property called ViewportLocked that prevents the viewport from being moved, resized, or reset. Locking the viewport makes the reset viewport button use a padlock symbol.
  • Added a callback in GraphForm for when the viewport is zoomed in or out.
  • Added an update checker. Runs in an asyncronous task so as to not lag startup on a poor connection.
  • Replaced the default text on selection with a more customizable method.
  • Replaced the selection system with a small state machine to control the various click-drag functions.
  • Added the ability to set the zoom of the graph form by drawing a box.
  • Added the ability to ungraph a graphable from the form.
  • Added a method to determine if a point on the graph is visible to the user.
  • The graph form now stores a reference to the current zoom form when opened to prevent duplicates.
  • Zooming in with the scroll wheel now focuses the zooming around the cursor's currently selected point.
  • Pressing the reset button now does a full reset instead of a previous partial one.
  • Added the ability to change a slope field's detail in the UI. Found under "Elements > Detail"
  • Reworked most of the original UI elements to hopefully be more extendable.
    • Added some more options. See above with the interfaces, those are most of them.
  • The zoom form now tries to appear to the right of the graph form (though if it goes off the screen it won't do that).
  • Added a public method to do a full reset of the viewport (ResetAllViewport()).
  • The graph form now stores a reference to the current cache form when opened to prevent duplicates.
  • Made a bunch of object senders nullable. Gotta be conventionally correct!
  • The zoom form has been completely reworked. Now it's a lot more customizable.
  • The cache form now ignores graphables with zero cache. Doesn't change much.
  • Replaced the method in the abstract Graphable class named DeepCopy() with one called ShallowCopy() since I wasn't actually doing any deep copying in my implementations of it.
  • The column table no longer does any deep copying. This was I think the one place I actually used deep-copied internal variables.
  • Added new selection code for the ColumnTable.
  • Implemented a bunch of the earlier abstract interfaces in the Equation graphable (specifically ITranslatableXY, and IConvertSlopeField).
  • Added a callback for when the equation is rendered. I don't use it much and I'll probably get rid of it, having callbacks in graphables is not recommended.
  • Added the ability for an equation to convert to its slope field.
  • Added the ability for an equation to convert to a column table.
  • Added a public method in the Equation graphable for getting an exact value from it.
  • Slightly reworked the selection text in the Equation graphable.
  • Added a graphable that displays the difference between two equations, called the EquationDifference. It can convert to an equation that displays the difference over x and can be translated.
  • Slightly reworked the selection text in the IntegralEquation graphable.
  • Added a ParametricEquation graphable. It takes in two delegates, one for x over time and one for y.
  • Made the detail in the SlopeField graphable a public property that can be modified. Also made it a double instead of an int. Reworked the renderer a bit so decimal slope fields work well.
  • Improved the SlopeField selection UI items to show the slope rather than the coordinates.
  • Made the TangentLine graphable implement the interfaces IConvertEquation and ITranslatableX.
  • Made the cache of the TangentLine clear when the parent is modified. The only use of a grap...
Read more

Graphing 1.2.0

21 Mar 16:38
a4e9ae3
Compare
Choose a tag to compare

Graphing 1.2.0

This is the third important release of the graphing calculator. This update is
fairly all over the place, but here are the important parts. First of all, the
system for integrating equations has been drastically improved. Originally, the
system was laggy for intensive equations and especially for second or third
order integrals, and the line itself would appear quite choppy if you zoom in
far enough. This was because the original system would compute the integral at
a point by just accumulating the area from 0 to that point. So if you asked for
the integral of an equation at 2.1 and then again at 2.2, the work for
calculating 2.1 would be done twice.

This has since been improved. There is a new graphable specifically for the
displaying integrals called the IntegralEquation. This graphable is a
modified version of the Equation graphable with some notable optimizations.
Now, rather than doing duplicate work when calculating points one-after-another
is done by increasing an internal stepper rather than recomputing from scratch.
The result makes integrating many points in order (which is done for hundreds
of points per frame) is now remarkably faster. High order integrals are now
almost as fast as their parent equation, and in this regard only, I think I
have a win against Desmos. Their integration can prove to be slower than mine.
Another benefit of this new method is that the change in the accumulation is
dependent on zoom, meaning the graph does not appear jagged or choppy at all
when you zoom in. It has a side of effect of making the graph more laggy when
you zoon in a whole bunch, but for most purposes, this system is much faster.

I've also made the line thickness of the graph dependent on the DPI of the
monitor used. I honestly would've thought that Windows Forms would handle that
part for me, but it doesn't. So in the GraphForm there is now a new property
called DpiFloat which represents the DPI of the screen. All the graph parts
now have their line thickness scaled by a factor of DpiFloat / 192, since my
development display has a DPI of 192, I'm using that for reference. It's a bit
redundant though. I think in a future update (marked on the project board),
I'll replace the DpiFloat / 192 system with a simpler DpiFactor property.

And I've made some light progress on a more modular approach to applying
operators to graphs. Currently you can only integrate and derive in the UI,
but I've replaced the simple check for an Equation type with a more modular
interface check. To make your graphable appear in the derivation menu, make
your graphable implement the IDerivable interface.

That's about it for now. If you want the specific changelog, it's below:


  • Added .github/ to the Gitignore. Not sure why it's appeared but I'm adding it just in case.
  • Added the following feature interfaces:
    • IDerivable - Used to derive graphs.
    • IIntegrable - Used to integrate graphs.
  • Disabled implicit usings in the project properties. It's mostly for debugging help.
  • Added some more NuGet tags.
  • Added the DpiFloat property to the GraphForm for use with scaling UI elements.
    • Also added the DpiFloat property to the PieChart control for the same purpose.
  • The PieChart control no longer draws an extraneous edge when there's only one item on the chart.
  • Increased the maximum zoom level from 0.01 to 0.00001.
  • The form now draws units on the main axes which scale with zoom level.
    • There is now a UnitsTextColor constant for the text color.
  • Created a graph selection detection system for specific graphables.
    • Stores generated pens to prevent duplicate work.
    • Prevents scrolling the screen when selecting a graph.
  • The color picker form now won't appear partially or entirely off the edge of the screen.
  • Replaced generating UI options for equations with generating UI options for individual interfaces.
    • Currently IDerivable and IIntegrable.
  • Replaced the old EquationComputeDerivative_Click method with a simpler Graph(derivable.Derive()) method.
  • Replaced the old EquationComputeIntegral_Click method with a simpler Graph(integrable.Integrate()) method.
  • The cache form now won't appear partially or entirely off the edge of the screen.
  • The cache form now is always shown on top of the main form.
  • Added the ability to preload graphables at a higher depth.
  • Made the buttons for the cache viewer variables and made them scale with DPI.
  • Got rid of the very slight transparency in preset graph colors.
  • Made all optional methods virtual instead of abstract.
  • Added the following optional methods to the base Graphable type:
    • void Preload(Float2, Float2, double)
    • bool ShouldSelectGraphable(in GraphForm, Float2, double)
    • Float2 GetSelectedPoint(in GraphForm, Float2)
  • Removed the unused EraseCache method in ColumnTable
  • Made the Equation graphable implement IDerivable and IIntegrable.
  • The equation sampling rate now scales with DPI.
  • Added the ability to select a point along an equation.
  • The equation now draws the extra little bit that was previously missing on the right side of the screen.
  • Added the IntegralEquation, which can integrate equations much faster than the standard method.
  • Added the ability to select a point along a SlopeField.
  • Made the Position property of a TangentLine more dynamic.
  • Added the ability to cache previous heights and slopes in a TangentLine automatically.
  • In TangentLine, made the MakeSlopeLine use already-existing properties rather than arguments.
  • Added a caching system to DerivativeAtPoint in TangentLine.
  • Added implementations to EraseCache and GetCacheBytes in TangentLine.
  • Added the ability to select a point along a tangent line.
  • Replaced the Render method passing a Brush with one passing a Pen to prevent duplicate work.
  • Modified the README some.
  • Changed the demonstration default.

Graphing 1.1.0

13 Mar 14:37
a93b585
Compare
Choose a tag to compare

Graphing 1.1.0

This is the second release of the graphing calculator. This update focuses more
on the optimization of general equations in the engine. The main improvement is
that the original computing method would do a whole lot of duplicate work if
you moved the viewport. We've already calculate the value of the equation at a
given point, we shouldn't have to do that again.

So in this update, a caching system has been implemented. It is most targeted
to the Equation graphable, but also partially applies to the SlopeField
graphable. Values generated during rendering are cached by the graphable to be
reclaimed faster in future calls for a value at a given point. The caches get
fairly big but not huge. In all my testing, the cache rarely got above 2 MB.
The total cache depends of course on the amount of equations being graphed, but
assuming it remains at a reasonable level, the memory usage will certainly stay
in the single-digit megabyte range.

The cached data can be visualized in the UI by using the toolbar. Go to Misc >
View Caches to see the caches. A window will open up displaying a pie chart of
the memory usage and the ability to reset a given equation's cache. Note that
resetting a cache does not guarantee it will go entirely to zero, as some data
is required for the first-time render. But it will certainly shrink to just a
few kilobytes.

It's a medium-sized tweak, but I'm proud of it. In addition, I've also added
the some more graphables, including a tangent line of a equation at a point
(use the TangentLine graphable) and a simple bar graph (use the ColumnTable
graphable). I guess I've never specified directly, but you can script this
calculator. You can write your own graphables simply by deriving from the
abstract Graphable type and implementing the required methods. I may make a
wiki detailing how to write your own graphables in the future.

The other decent change is to add the ability to draw more than just lines.
Rather than a graphable generating just a collection of GraphLines, it now
generates a collection of IGraphParts, where GraphLine derives from. In
addition to a line now, a GraphUICircle exists, which draws a
constant-pixel-size circle at a position in graph space, and a
GraphRectangle, which draws a rectangle in graph space. The UI circle is used
in the tangent line graphable and the rectangle in the column table
respectively. More graph parts can be scripted as well, just by deriving from
the IGraphPart interface.

Anyway, that's the big stuff. Here's a more detailed list of every change:


  • Added the ability to format a number in terms of file size (eg. "1024" → "1.00 KB")
  • Added a form control that draws a pie chart given some values and colors.
  • Made the base graph colors (axis colors, semi-axis colors, etc.) static constants at the top of the file.
  • Enabled anti-aliasing in the graph.
  • Replaced the built-in line rendering scheme with a more generalized part rendering scheme.
    • Moved the code that renders lines from GraphForm:157-167 to GraphLine:23-30
  • Started using double.IsFinite as opposed to double.IsNormal, because apparently zero is not normal.
  • The GraphForm.Graph method now accepts a collection of items to graph rather than just one.
  • Prevented some extra casting when regenerating menu items.
  • Changed the integral step from 0.1 to 0.01.
  • Added a button in the UI that opens a form to view graph caches.
  • Replaced namespace with a file-scoped namespace in SetZoomForm
  • Added a form to view graph caches.
  • Replaced the return type of the abstract GetItemsToRender from an IEnumerable<Line2d> to an IEnumerable<GraphLine>.
  • Added the following abstract methods in Graphable
    • Graphable DeepCopy()
    • void EraseCache()
    • long GetCacheBytes()
  • Added the ColumnTable graphable which represents a bar graph.
  • Added a List<Float2> cache in the Equation graphable.
  • Rather than calling the delegate directly, the Equation attempts to load its cached value first.
  • Renamed Line2d to GraphLine
  • Added a List<Float2> cache in the Equation graphable.
  • Added a TangentLine graphable which represents a tangent of an equation at one point.
  • Added the IGraphPart interface.
  • Added a rectangle graph part (GraphRectangle).
  • Added a UI circle graph part (GraphUICircle).

Graphing 1.0.0

27 Feb 20:59
Compare
Choose a tag to compare

This is the initial version. Fairly simple but it all works.