From 3665b0547aa4cd5e80e8d83ba95936684c25f9fc Mon Sep 17 00:00:00 2001 From: That_One_Nerd Date: Sat, 23 Mar 2024 10:33:49 -0400 Subject: [PATCH] Nice progress. Some of it is bodged a bit but that's okay. --- Base/Forms/GraphForm.cs | 5 ++- Base/Graphable.cs | 2 +- Base/Graphables/ColumnTable.cs | 2 +- Base/Graphables/Equation.cs | 2 +- Base/Graphables/EquationDifference.cs | 58 +++++++++++++++++++++++++++ Base/Graphables/IntegralEquation.cs | 6 +-- Base/Graphables/SlopeField.cs | 2 +- Base/Graphables/TangentLine.cs | 4 +- Base/Parts/GraphUiCircle.cs | 2 +- Base/Parts/GraphUiText.cs | 38 ++++++++++++++++++ Testing/Program.cs | 13 ++---- 11 files changed, 113 insertions(+), 21 deletions(-) create mode 100644 Base/Graphables/EquationDifference.cs create mode 100644 Base/Parts/GraphUiText.cs diff --git a/Base/Forms/GraphForm.cs b/Base/Forms/GraphForm.cs index b266525..cc9b494 100644 --- a/Base/Forms/GraphForm.cs +++ b/Base/Forms/GraphForm.cs @@ -11,6 +11,7 @@ namespace Graphing.Forms; public partial class GraphForm : Form { + public static readonly Color BackgroundColor = Color.White; public static readonly Color MainAxisColor = Color.Black; public static readonly Color SemiAxisColor = Color.FromArgb(unchecked((int)0xFF_999999)); public static readonly Color QuarterAxisColor = Color.FromArgb(unchecked((int)0xFF_E0E0E0)); @@ -200,7 +201,7 @@ public partial class GraphForm : Form Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.HighQuality; - Brush background = new SolidBrush(Color.White); + Brush background = new SolidBrush(BackgroundColor); g.FillRectangle(background, e.ClipRectangle); PaintGrid(g); @@ -231,7 +232,7 @@ public partial class GraphForm : Form if (ables[i].ShouldSelectGraphable(this, graphMousePos, 2.5)) { Float2 selectedPoint = ables[i].GetSelectedPoint(this, graphMousePos); - GraphUiCircle select = new(selectedPoint, 8); + GraphUiCircle select = new(selectedPoint); Int2 textPos = GraphSpaceToScreenSpace(select.center); textPos.y -= (int)(DpiFloat * 32 / 192); diff --git a/Base/Graphable.cs b/Base/Graphable.cs index 2844ef7..e59f358 100644 --- a/Base/Graphable.cs +++ b/Base/Graphable.cs @@ -30,7 +30,7 @@ public abstract class Graphable public abstract IEnumerable GetItemsToRender(in GraphForm graph); - public abstract Graphable DeepCopy(); + public abstract Graphable ShallowCopy(); public virtual void EraseCache() { } public virtual long GetCacheBytes() => 0; diff --git a/Base/Graphables/ColumnTable.cs b/Base/Graphables/ColumnTable.cs index 0461cc3..55142d4 100644 --- a/Base/Graphables/ColumnTable.cs +++ b/Base/Graphables/ColumnTable.cs @@ -37,7 +37,7 @@ public class ColumnTable : Graphable public override long GetCacheBytes() => 16 * tableXY.Count; - public override Graphable DeepCopy() => new ColumnTable(width / 0.75, tableXY.ToArray().ToDictionary()); + public override Graphable ShallowCopy() => new ColumnTable(width / 0.75, tableXY); public override IEnumerable GetItemsToRender(in GraphForm graph) { diff --git a/Base/Graphables/Equation.cs b/Base/Graphables/Equation.cs index da7fa61..ef9c514 100644 --- a/Base/Graphables/Equation.cs +++ b/Base/Graphables/Equation.cs @@ -116,7 +116,7 @@ public class Equation : Graphable, IIntegrable, IDerivable, ITranslatableXY } } - public override Graphable DeepCopy() => new Equation(equ); + public override Graphable ShallowCopy() => new Equation(equ); public override long GetCacheBytes() => cache.Count * 16; diff --git a/Base/Graphables/EquationDifference.cs b/Base/Graphables/EquationDifference.cs new file mode 100644 index 0000000..2f07d99 --- /dev/null +++ b/Base/Graphables/EquationDifference.cs @@ -0,0 +1,58 @@ +using Graphing.Abstract; +using Graphing.Forms; +using Graphing.Parts; +using System.Collections.Generic; + +namespace Graphing.Graphables; + +public class EquationDifference : Graphable, ITranslatableX, IEquationConvertible +{ + public double Position + { + get => _position; + set + { + _position = value; + points = new Float2(equA.GetValueAt(value), equB.GetValueAt(value)); + } + } + private double _position; + + public double OffsetX + { + get => Position; + set => Position = value; + } + + protected readonly Equation equA, equB; + protected Float2 points; // X represents equA.y, Y represents equB.y + + public EquationDifference(double position, Equation equA, Equation equB) + { + this.equA = equA; + this.equB = equB; + + Name = $"Difference between {equA.Name} and {equB.Name}"; + + Position = position; + } + + public override IEnumerable GetItemsToRender(in GraphForm graph) + { + Float2 pA = new(Position, points.x), + pB = new(Position, points.y), + pC = new(Position, (points.x + points.y) / 2); + return [new GraphUiText($"{points.x - points.y:0.00}", pC), + new GraphUiCircle(pA), new GraphUiCircle(pB), new GraphLine(pA, pB)]; + } + + public double DistanceAtPoint(double x) => equA.GetValueAt(x) - equB.GetValueAt(x); + + public override Graphable ShallowCopy() => new EquationDifference(Position, equA, equB); + + public Equation ToEquation() => new(DistanceAtPoint) + { + Color = Color, + Name = Name + }; +} diff --git a/Base/Graphables/IntegralEquation.cs b/Base/Graphables/IntegralEquation.cs index 51742fd..2279b0d 100644 --- a/Base/Graphables/IntegralEquation.cs +++ b/Base/Graphables/IntegralEquation.cs @@ -47,7 +47,7 @@ public class IntegralEquation : Graphable, IIntegrable, IDerivable usingAlt = true; } - public override Graphable DeepCopy() => new IntegralEquation(this); + public override Graphable ShallowCopy() => new IntegralEquation(this); public override IEnumerable GetItemsToRender(in GraphForm graph) { @@ -178,8 +178,8 @@ public class IntegralEquation : Graphable, IIntegrable, IDerivable public Graphable Derive() { - if (usingAlt) return altBaseEqu!.DeepCopy(); - else return (Equation)baseEqu!.DeepCopy(); + if (usingAlt) return altBaseEqu!.ShallowCopy(); + else return (Equation)baseEqu!.ShallowCopy(); } public Graphable Integrate() => new IntegralEquation(this); diff --git a/Base/Graphables/SlopeField.cs b/Base/Graphables/SlopeField.cs index 066f658..d9a4549 100644 --- a/Base/Graphables/SlopeField.cs +++ b/Base/Graphables/SlopeField.cs @@ -72,7 +72,7 @@ public class SlopeField : Graphable return result; } - public override Graphable DeepCopy() => new SlopeField(detail, equ); + public override Graphable ShallowCopy() => new SlopeField(detail, equ); public override void EraseCache() => cache.Clear(); public override long GetCacheBytes() => cache.Count * 48; diff --git a/Base/Graphables/TangentLine.cs b/Base/Graphables/TangentLine.cs index 9f5c2e1..5cc2da5 100644 --- a/Base/Graphables/TangentLine.cs +++ b/Base/Graphables/TangentLine.cs @@ -56,7 +56,7 @@ public class TangentLine : Graphable, IEquationConvertible, ITranslatableX public override IEnumerable GetItemsToRender(in GraphForm graph) { Float2 point = new(Position, currentSlope.y); - return [MakeSlopeLine(), new GraphUiCircle(point, 8)]; + return [MakeSlopeLine(), new GraphUiCircle(point)]; } protected GraphLine MakeSlopeLine() { @@ -81,7 +81,7 @@ public class TangentLine : Graphable, IEquationConvertible, ITranslatableX return result; } - public override Graphable DeepCopy() => new TangentLine(length, Position, parent); + public override Graphable ShallowCopy() => new TangentLine(length, Position, parent); public override void EraseCache() => slopeCache.Clear(); public override long GetCacheBytes() => slopeCache.Count * 24; diff --git a/Base/Parts/GraphUiCircle.cs b/Base/Parts/GraphUiCircle.cs index 7f46411..8221a46 100644 --- a/Base/Parts/GraphUiCircle.cs +++ b/Base/Parts/GraphUiCircle.cs @@ -13,7 +13,7 @@ public record struct GraphUiCircle : IGraphPart center = new(); radius = 1; } - public GraphUiCircle(Float2 center, int radius) + public GraphUiCircle(Float2 center, int radius = 8) { this.center = center; this.radius = radius; diff --git a/Base/Parts/GraphUiText.cs b/Base/Parts/GraphUiText.cs new file mode 100644 index 0000000..0d27573 --- /dev/null +++ b/Base/Parts/GraphUiText.cs @@ -0,0 +1,38 @@ +using Graphing.Forms; +using System.Drawing; + +namespace Graphing.Parts; + +public record struct GraphUiText : IGraphPart +{ + public string text; + public Float2 position; + public bool background; + + private readonly Font font; + private readonly Brush? backgroundBrush; + + public GraphUiText(string text, Float2 position, bool background = true) + { + font = new Font("Segoe UI", 8, FontStyle.Bold); + + this.text = text; + this.position = position; + this.background = background; + + if (background) backgroundBrush = new SolidBrush(GraphForm.BackgroundColor); + } + + public readonly void Render(in GraphForm form, in Graphics g, in Pen p) + { + Int2 posScreen = form.GraphSpaceToScreenSpace(position); + posScreen.y -= (int)(form.DpiFloat * font.Size * 2 / 192); + if (background) + { + SizeF size = g.MeasureString(text, font); + g.FillRectangle(backgroundBrush!, new Rectangle(posScreen.x, posScreen.y, + (int)size.Width, (int)size.Height)); + } + g.DrawString(text, font, p.Brush, new Point(posScreen.x, posScreen.y)); + } +} diff --git a/Testing/Program.cs b/Testing/Program.cs index 851e7f8..2c58989 100644 --- a/Testing/Program.cs +++ b/Testing/Program.cs @@ -16,15 +16,10 @@ internal static class Program GraphForm graph = new("One Of The Graphing Calculators Of All Time"); - Equation equ = new(Math.Sin); - SlopeField sf = new(2, (x, y) => Math.Cos(x)); - TangentLine tl = new(2, 2, equ); - graph.Graph(equ, sf, tl); - - // Now, when integrating equations, the result is much less jagged - // and much faster. Try it out! You can also select points along - // equations and such as well. Click on an equation to see for - // yourself! + Equation equA = new(Math.Sin), + equB = new(Math.Cos); + EquationDifference diff = new(2, equA, equB); + graph.Graph(equA, equB, diff); Application.Run(graph); }