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

View File

@ -466,12 +466,16 @@ public partial class GraphForm : Form
Float2 min = MinVisibleGraph, max = MaxVisibleGraph;
Float2 add = new(max.x - min.x, max.y - min.y);
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),
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);
}
}

View File

@ -32,7 +32,7 @@ public abstract class Graphable
public abstract void EraseCache();
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 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 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));
}
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 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);

View File

@ -5,17 +5,32 @@ namespace Graphing.Graphables;
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 EquationDelegate parentEqu;
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)
{
Name = $"Tangent Line of {parent.Name}";
slopeCache = [];
parentEqu = parent.GetDelegate();
Position = position;
this.length = length;
@ -25,7 +40,7 @@ public class TangentLine : Graphable
public override IEnumerable<IGraphPart> GetItemsToRender(in GraphForm graph)
{
Float2 point = new(Position, parentEqu(Position));
return [MakeSlopeLine(point, DerivativeAtPoint(Position)),
return [MakeSlopeLine(point, currentSlope),
new GraphUiCircle(point, 8)];
}
protected GraphLine MakeSlopeLine(Float2 position, double slope)
@ -40,17 +55,29 @@ public class TangentLine : Graphable
}
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;
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 void EraseCache() { }
public override long GetCacheBytes() => 0;
public override void EraseCache() => slopeCache.Clear();
public override long GetCacheBytes() => slopeCache.Count * 16;
public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false;
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");
Equation equ1 = new(x => -x * x + 2);
Equation equ2 = new(x => x);
Equation equ3 = new(x => -Math.Sqrt(x));
graph.Graph(equ1, equ2, equ3);
Equation possibleA = new(x => x * x * x);
SlopeField sf = new(2, (x, y) => 3 * x * x);
TangentLine tl = new(5, 2, possibleA);
graph.Graph(possibleA, sf, tl);
// You can also now view and reset caches in the UI by going to
// Misc > View Caches.