Made preload functions for most of the other graphables.
This commit is contained in:
parent
255a7d3774
commit
5c3cf9cafe
@ -46,16 +46,21 @@ public partial class PieChart : UserControl
|
|||||||
current += item.value;
|
current += item.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the outline.
|
// Draw the outline of each slice.
|
||||||
Pen outlinePartsPen = new(Color.FromArgb(unchecked((int)0xFF_202020)), DpiFloat * 3 / 192);
|
// Only done if there is more than one slice.
|
||||||
current = 0;
|
if (Values.Count > 1)
|
||||||
foreach ((Color, double value) item in Values)
|
|
||||||
{
|
{
|
||||||
double start = 360 * current / sum,
|
Pen outlinePartsPen = new(Color.FromArgb(unchecked((int)0xFF_202020)), DpiFloat * 3 / 192);
|
||||||
end = 360 * (current + item.value) / sum;
|
current = 0;
|
||||||
g.DrawPie(outlinePartsPen, rect, (float)start, (float)(end - start));
|
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
|
// Outline
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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) { }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user