Made preload functions for most of the other graphables.

This commit is contained in:
That_One_Nerd 2024-03-18 08:57:00 -04:00
parent 255a7d3774
commit 5c3cf9cafe
8 changed files with 71 additions and 25 deletions

View File

@ -46,17 +46,22 @@ public partial class PieChart : UserControl
current += item.value; current += item.value;
} }
// Draw the outline. // Draw the outline of each slice.
// Only done if there is more than one slice.
if (Values.Count > 1)
{
Pen outlinePartsPen = new(Color.FromArgb(unchecked((int)0xFF_202020)), DpiFloat * 3 / 192); Pen outlinePartsPen = new(Color.FromArgb(unchecked((int)0xFF_202020)), DpiFloat * 3 / 192);
current = 0; current = 0;
foreach ((Color, double value) item in Values) foreach ((Color, double value) item in Values)
{ {
double start = 360 * current / sum, double start = 360 * current / sum,
end = 360 * (current + item.value) / sum; end = 360 * (current + item.value) / sum;
if (item.value > 0)
g.DrawPie(outlinePartsPen, rect, (float)start, (float)(end - start)); g.DrawPie(outlinePartsPen, rect, (float)start, (float)(end - start));
current += item.value; current += item.value;
} }
}
// Outline // Outline
Pen outlinePen = new(Color.FromArgb(unchecked((int)0xFF_202020)), DpiFloat * 5 / 192); Pen outlinePen = new(Color.FromArgb(unchecked((int)0xFF_202020)), DpiFloat * 5 / 192);

View File

@ -466,12 +466,16 @@ public partial class GraphForm : Form
Float2 min = MinVisibleGraph, max = MaxVisibleGraph; Float2 min = MinVisibleGraph, max = MaxVisibleGraph;
Float2 add = new(max.x - min.x, max.y - min.y); Float2 add = new(max.x - min.x, max.y - min.y);
add.x *= 0.75; // Expansion add.x *= 0.75; // Expansion
add.y *= 0.75; // add.y *= 0.75; // Screen + 75%
Float2 xRange = new(min.x - add.x, max.x + add.x), Float2 xRange = new(min.x - add.x, max.x + add.x),
yRange = new(min.y - add.y, max.y + add.y); yRange = new(min.y - add.y, max.y + add.y);
foreach (Graphable able in Graphables) able.Preload(xRange, yRange); double step = ScreenSpaceToGraphSpace(new Int2(1, 0)).x
- ScreenSpaceToGraphSpace(new Int2(0, 0)).x;
step /= 10;
foreach (Graphable able in Graphables) able.Preload(xRange, yRange, step);
Invalidate(false); Invalidate(false);
} }
} }

View File

@ -32,7 +32,7 @@ public abstract class Graphable
public abstract void EraseCache(); public abstract void EraseCache();
public abstract long GetCacheBytes(); public abstract long GetCacheBytes();
public abstract void Preload(Float2 xRange, Float2 yRange); public abstract void Preload(Float2 xRange, Float2 yRange, double step);
public abstract bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor); public abstract bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor);
public abstract Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos); public abstract Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos);

View File

@ -52,5 +52,6 @@ public class ColumnTable : Graphable
public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false; public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false;
public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos) => default; public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos) => default;
public override void Preload(Float2 xRange, Float2 yRange) { } // Nothing to preload, everything is already cached.
public override void Preload(Float2 xRange, Float2 yRange, double step) { }
} }

View File

@ -116,9 +116,9 @@ public class Equation : Graphable
return new(graphMousePos.x, GetFromCache(graphMousePos.x, 0.001)); return new(graphMousePos.x, GetFromCache(graphMousePos.x, 0.001));
} }
public override void Preload(Float2 xRange, Float2 yRange) public override void Preload(Float2 xRange, Float2 yRange, double step)
{ {
for (double x = xRange.x; x <= xRange.y; x += 1e-3) GetFromCache(x, 1e-4); for (double x = xRange.x; x <= xRange.y; x += step) GetFromCache(x, step);
} }
} }

View File

@ -78,7 +78,16 @@ public class SlopeField : Graphable
public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false; public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false;
public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos) => default; public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos) => default;
public override void Preload(Float2 xRange, Float2 yRange) { } public override void Preload(Float2 xRange, Float2 yRange, double step)
{
for (double x = Math.Ceiling(xRange.x - 1); x < xRange.y + 1; x += 1.0 / detail)
{
for (double y = Math.Ceiling(yRange.x - 1); y < yRange.y + 1; y += 1.0 / detail)
{
GetFromCache(step, x, y);
}
}
}
} }
public delegate double SlopeFieldsDelegate(double x, double y); public delegate double SlopeFieldsDelegate(double x, double y);

View File

@ -5,17 +5,32 @@ namespace Graphing.Graphables;
public class TangentLine : Graphable public class TangentLine : Graphable
{ {
public double Position { get; set; } public double Position
{
get => _position;
set
{
currentSlope = DerivativeAtPoint(value);
_position = value;
}
}
private double _position;
protected readonly Equation parent; protected readonly Equation parent;
protected readonly EquationDelegate parentEqu; protected readonly EquationDelegate parentEqu;
protected readonly double length; protected readonly double length;
protected double currentSlope;
// No binary search for this, I want it to be exact.
protected Dictionary<double, double> slopeCache;
public TangentLine(double length, double position, Equation parent) public TangentLine(double length, double position, Equation parent)
{ {
Name = $"Tangent Line of {parent.Name}"; Name = $"Tangent Line of {parent.Name}";
slopeCache = [];
parentEqu = parent.GetDelegate(); parentEqu = parent.GetDelegate();
Position = position; Position = position;
this.length = length; this.length = length;
@ -25,7 +40,7 @@ public class TangentLine : Graphable
public override IEnumerable<IGraphPart> GetItemsToRender(in GraphForm graph) public override IEnumerable<IGraphPart> GetItemsToRender(in GraphForm graph)
{ {
Float2 point = new(Position, parentEqu(Position)); Float2 point = new(Position, parentEqu(Position));
return [MakeSlopeLine(point, DerivativeAtPoint(Position)), return [MakeSlopeLine(point, currentSlope),
new GraphUiCircle(point, 8)]; new GraphUiCircle(point, 8)];
} }
protected GraphLine MakeSlopeLine(Float2 position, double slope) protected GraphLine MakeSlopeLine(Float2 position, double slope)
@ -40,17 +55,29 @@ public class TangentLine : Graphable
} }
protected double DerivativeAtPoint(double x) protected double DerivativeAtPoint(double x)
{ {
// If value is already computed, return it.
if (slopeCache.TryGetValue(x, out double y)) return y;
const double step = 1e-3; const double step = 1e-3;
return (parentEqu(x + step) - parentEqu(x)) / step; double result = (parentEqu(x + step) - parentEqu(x)) / step;
slopeCache.Add(x, result);
return result;
} }
public override Graphable DeepCopy() => new TangentLine(length, Position, parent); public override Graphable DeepCopy() => new TangentLine(length, Position, parent);
public override void EraseCache() { } public override void EraseCache() => slopeCache.Clear();
public override long GetCacheBytes() => 0; public override long GetCacheBytes() => slopeCache.Count * 16;
public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false; public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false;
public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos) => default; public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos) => default;
public override void Preload(Float2 xRange, Float2 yRange) { } public override void Preload(Float2 xRange, Float2 yRange, double step)
{
// Despite the tangent line barely using any data, when preloaded it
// will always take as much memory as an equation. Seems like a bit much,
// but may be used when the tangent line is moved. Not sure there's much
// that can be changed.
for (double x = xRange.x; x <= xRange.y; x += step) DerivativeAtPoint(x);
}
} }

View File

@ -14,10 +14,10 @@ internal static class Program
GraphForm graph = new("One Of The Graphing Calculators Of All Time"); GraphForm graph = new("One Of The Graphing Calculators Of All Time");
Equation equ1 = new(x => -x * x + 2); Equation possibleA = new(x => x * x * x);
Equation equ2 = new(x => x); SlopeField sf = new(2, (x, y) => 3 * x * x);
Equation equ3 = new(x => -Math.Sqrt(x)); TangentLine tl = new(5, 2, possibleA);
graph.Graph(equ1, equ2, equ3); graph.Graph(possibleA, sf, tl);
// You can also now view and reset caches in the UI by going to // You can also now view and reset caches in the UI by going to
// Misc > View Caches. // Misc > View Caches.