Skip to content

Commit

Permalink
Logarithmically scaled gridlines
Browse files Browse the repository at this point in the history
  • Loading branch information
VoidXH committed Aug 3, 2023
1 parent c66f2b5 commit e22d41a
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 35 deletions.
49 changes: 33 additions & 16 deletions Cavern.QuickEQ/Graphing/Overlays/Frame.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Cavern.QuickEQ.Graphing.Overlays {
using System.Runtime.CompilerServices;

namespace Cavern.QuickEQ.Graphing.Overlays {
/// <summary>
/// Draws a frame of a given <see cref="Width"/> over the graph.
/// </summary>
Expand Down Expand Up @@ -27,25 +29,40 @@ public Frame(int width, uint color) {
/// Adds the overlay to a graph.
/// </summary>
public override void DrawOn(GraphRenderer target) {
// Edge rows
DrawRow(target, 0, Width, color);
DrawRow(target, target.Height - Width, Width, color);
DrawColumn(target, 0, Width, color);
DrawColumn(target, target.Width - Width, Width, color);
}

/// <summary>
/// Draw a single row at a height <paramref name="offset"/> of a developing image.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void DrawRow(GraphRenderer target, int offset, int width, uint color) {
uint[] pixels = target.Pixels;
int until = target.Width * Width;
for (int i = 0; i < until; i++) {
pixels[i] = color;
}
for (int i = pixels.Length - until; i < pixels.Length; i++) {
pixels[i] = color;
while (width > 0) {
for (int y = offset * target.Width, end = y + target.Width; y < end; y++) {
pixels[y] = color;
}
offset++;
width--;
}
}

// Edge columns
for (int x = 0; x < Width; x++) {
int c = target.Height - Width;
for (int y = Width; y < c; y++) {
pixels[y * target.Width + x] = color;
}
for (int y = Width; y < c; y++) {
pixels[pixels.Length - y * target.Width - x] = color;
/// <summary>
/// Draw a single column at a width <paramref name="offset"/> of a developing image.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void DrawColumn(GraphRenderer target, int offset, int width, uint color) {
uint[] pixels = target.Pixels;
while (width > 0) {
for (int y = 0, pos = offset, step = target.Width; y < target.Height; y++) {
pixels[pos] = color;
pos += step;
}
offset++;
width--;
}
}
}
Expand Down
24 changes: 5 additions & 19 deletions Cavern.QuickEQ/Graphing/Overlays/Grid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,15 @@ public Grid(int borderWidth, int gridWidth, uint color, int xSteps, int ySteps)
/// </summary>
public override void DrawOn(GraphRenderer target) {
base.DrawOn(target);
uint[] pixels = target.Pixels;
int xGap = target.Width / xSteps,
yGap = target.Height / ySteps,
yMax = target.Height - Width;

int gap = target.Width / xSteps;
for (int x = 1; x < xSteps; x++) {
int xPos = x * xGap;
for (int y = Width; y <= yMax; y++) {
int start = y * target.Width + xPos;
for (int w = 0; w < gridWidth; w++) {
pixels[start + w] = color;
}
}
DrawColumn(target, x * gap, gridWidth, color);
}

int xMax = target.Width - Width;
gap = target.Height / ySteps;
for (int y = 1; y < ySteps; y++) {
int yPos = y * yGap;
for (int w = 0; w < gridWidth; w++) {
int start = (yPos + w) * target.Width;
for (int x = Width; x <= xMax; x++) {
pixels[start + x] = color;
}
}
DrawRow(target, y * gap, gridWidth, color);
}
}
}
Expand Down
54 changes: 54 additions & 0 deletions Cavern.QuickEQ/Graphing/Overlays/LogScaleGrid.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Cavern.Utilities;
using System;

namespace Cavern.QuickEQ.Graphing.Overlays {
/// <summary>
/// Draws a grid over the graph with a gridline at every increment of the highest local value.
/// </summary>
public class LogScaleGrid : Frame {
/// <summary>
/// Inner line stroke width.
/// </summary>
readonly int gridWidth;

/// <summary>
/// Number of rows drawn, including the frame lines.
/// </summary>
readonly int ySteps;

/// <summary>
/// Draws a grid over the graph with a gridline at every increment of the highest local value.
/// </summary>
/// <param name="borderWidth">Border line stroke width</param>
/// <param name="gridWidth">Inner line stroke width</param>
/// <param name="color">RGBA color of the line</param>
/// <param name="ySteps">Number of rows drawn, including the frame lines</param>
public LogScaleGrid(int borderWidth, int gridWidth, uint color, int ySteps) : base(borderWidth, color) {
this.gridWidth = gridWidth;
this.ySteps = ySteps;
}

/// <summary>
/// Adds the overlay to a graph.
/// </summary>
public override void DrawOn(GraphRenderer target) {
base.DrawOn(target);

int gap = target.Height / ySteps;
for (int y = 1; y < ySteps; y++) {
DrawRow(target, y * gap, gridWidth, color);
}

float logStart = MathF.Log10(target.StartFrequency),
logEnd = MathF.Log10(target.EndFrequency);
for (int digit = (int)logStart, last = (int)logEnd; digit <= last; digit++) {
for (int value = 1; value < 10; value++) {
float freq = value * MathF.Pow(10, digit);
if (freq > target.StartFrequency && freq < target.EndFrequency) {
DrawColumn(target, (int)(target.Width * QMath.LerpInverse(logStart, logEnd, MathF.Log10(freq))), gridWidth, color);
}
}
}
}
}
}

0 comments on commit e22d41a

Please sign in to comment.