Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@
<Compile Include="Models\KeyboardOutputServiceState.cs" />
<Compile Include="Models\KeyCommand.cs" />
<Compile Include="Models\ScalingModels\ISensitivityFunction.cs" />
<Compile Include="Models\ScalingModels\RegionScaling.cs" />
<Compile Include="Models\ScalingModels\Region.cs" />
<Compile Include="Models\ScalingModels\SegmentScaling.cs" />
<Compile Include="Models\ScalingModels\SensitivityFunctionFactory.cs" />
<Compile Include="Models\ScalingModels\PiecewiseScaling.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Windows;

namespace JuliusSweetland.OptiKey.Models.ScalingModels
{
interface ISensitivityFunction
{
Vector CalculateScaling(Point current, Point centre);
List<Point> GetContours();
bool Contains(Point point);
List<Region> GetContours();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ public void SetCoords(float[] list_of_all_coords)
}
}

public List<Point> GetContours()
public List<Region> GetContours()
{
List<Point> ctrs = new List<Point>();
List<Region> ctrs = new List<Region>();
float lastVal = 0;
float lastX = 0;
foreach (var coord in individualCoords)
Expand All @@ -72,12 +72,12 @@ public List<Point> GetContours()
if (lastVal == 0 && currVal > 0)
{
// previous contour was zero-crossing
ctrs.Add(new Point(screenScale * lastX, screenScale * lastX));
ctrs.Add(new Region(.5 - lastX, .5 - lastX * Graphics.PrimaryScreenWidthInPixels / Graphics.PrimaryScreenHeightInPixels, 2 * lastX, 2 * lastX * Graphics.PrimaryScreenWidthInPixels / Graphics.PrimaryScreenHeightInPixels, 2 * lastX));
}
else if (lastVal > 0 && currVal == 0)
{
// new contour is zero-crossing
ctrs.Add(new Point(screenScale * currX, screenScale * currX));
ctrs.Add(new Region(.5 - currX, .5 - currX * Graphics.PrimaryScreenWidthInPixels / Graphics.PrimaryScreenHeightInPixels, 2 * currX, 2 * currX * Graphics.PrimaryScreenWidthInPixels / Graphics.PrimaryScreenHeightInPixels, 2 * currX));
}
lastVal = currVal;
lastX = currX;
Expand All @@ -86,7 +86,6 @@ public List<Point> GetContours()
return ctrs;
}


private float map_val(float f)
{
foreach (var pair in pairwiseCoords)
Expand Down Expand Up @@ -118,11 +117,6 @@ public Vector CalculateScaling(Point current, Point centre)
// Map back to x, y
return new Vector(amount * Math.Cos((double)theta), amount * Math.Sin((double)theta));
}

private double signedSqrt(double x)
{
// return sqrt of magnitude but with original sign
return Math.Sign(x) * Math.Sqrt(Math.Abs(x));
}
public bool Contains(Point point) { return true; }
}
}
39 changes: 39 additions & 0 deletions src/JuliusSweetland.OptiKey.Core/Models/ScalingModels/Region.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Windows;

namespace JuliusSweetland.OptiKey.Models.ScalingModels
{
public struct Region
{
public Region(double left, double top, double width, double height,
double radius = 0, double amount = 0, double gradient = .5, bool visible = false)
{
Left = left;
Top = top;
Width = width;
Height = height;
Radius = radius;
Amount = amount;
Gradient = gradient;
Visible = visible;
}
public double Left;
public double Top;
public double Width;
public double Height;
public double Radius;
public double Amount;
public double Gradient;
public bool Visible;
public Point Center { get { return new Point(Left + Width / 2, Top + Height / 2); } }
public double Right { get { return Left + Width; } }
public double Bottom { get { return Top + Height; } }
public bool Contains(double x, double y)
{
if (Radius > 0) //use ellipse logic
return Math.Pow(x, 2) / Math.Pow(Width / 2, 2) + Math.Pow(y, 2) / Math.Pow(Height / 2, 2) <= 1;
else //use rectangle logic
return x >= Left && x <= Right && y >= Top && y <= Bottom;
}
}
}
114 changes: 114 additions & 0 deletions src/JuliusSweetland.OptiKey.Core/Models/ScalingModels/RegionScaling.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using JuliusSweetland.OptiKey.Static;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

namespace JuliusSweetland.OptiKey.Models.ScalingModels
{
class RegionScaling : ISensitivityFunction
{
private List<Region> deadzones;
private List<Region> regions;

public RegionScaling(List<Region> deadzones, List<Region> regions)
{
this.deadzones = deadzones;
this.regions = regions;
}

public List<Region> GetContours()
{
var regions = this.regions;
if (deadzones!= null && deadzones.Any())
{
regions.AddRange(deadzones);
}

var ctrs = new List<Region>();
ctrs.AddRange(regions.Where(r => r.Visible));

return ctrs;
}

public Vector CalculateScaling(Point point, Point centre)
{
point.X /= Graphics.PrimaryScreenWidthInPixels;
point.Y /= Graphics.PrimaryScreenHeightInPixels;

if (regions.First().Radius > 0)
return RingScaling(point);
else
return RectangleScaling(point);
}

public Vector RingScaling(Point point)
{
var amount = 0d;
var vector = point - regions[0].Center;

for (int i = 0; i < regions.Count() - 1; i++)
{
var min = regions[i];
var max = regions[i + 1];

if (!(min.Contains(point.X, point.Y) && max.Contains(point.X, point.Y)))
{
var delta = vector.Length - min.Radius;
var maxDelta = max.Radius - min.Radius;
amount = max.Gradient == 0 ? min.Amount : max.Gradient == 1 ? max.Amount
: max.Gradient == .5 ? min.Amount + (max.Amount - min.Amount) * delta / maxDelta
: min.Amount + (max.Amount - min.Amount) * Math.Pow(delta / maxDelta, 2 * max.Gradient);
}
}

var theta = Math.Atan2(vector.Y, vector.X);
return new Vector(amount * Math.Cos(theta), amount * Math.Sin(theta));
}

public Vector RectangleScaling(Point point)
{
var amountX = 0d;
var amountY = 0d;

for (int i = 0; i < regions.Count() - 1; i++)
{
var min = regions[i];
var max = regions[i + 1];

if (!(min.Left <= point.X && min.Right >= point.X) && max.Left <= point.X && max.Right >= point.X)
{
var sX = point.X < min.Left ? -1 : 1;
var deltaX = sX < 0 ? min.Left - point.X : point.X - min.Right;
var maxX = sX < 0 ? min.Left - max.Left : max.Right - min.Right;
amountX = max.Gradient == 0 ? min.Amount : max.Gradient == 1 ? max.Amount
: max.Gradient == .5 ? min.Amount + (max.Amount - min.Amount) * deltaX / maxX
: min.Amount + (max.Amount - min.Amount) * Math.Pow(deltaX / maxX, 2 * max.Gradient);
amountX *= sX;
}

if (!(min.Top <= point.Y && min.Bottom >= point.Y) && max.Top <= point.Y && max.Bottom >= point.Y)
{
var sY = point.Y < min.Top ? -1 : point.Y > min.Bottom ? 1 : 0;
var deltaY = sY < 0 ? min.Top - point.Y : point.Y - min.Bottom;
var maxY = sY < 0 ? min.Top - max.Top : max.Bottom - min.Bottom;
amountY = max.Gradient == 0 ? min.Amount : max.Gradient == 1 ? max.Amount
: max.Gradient == .5 ? min.Amount + (max.Amount - min.Amount) * deltaY / maxY
: min.Amount + (max.Amount - min.Amount) * Math.Pow(deltaY / maxY, 2 * max.Gradient);
amountY *= sY;
}
}

return new Vector(amountX, amountY);
}

public bool Contains(Point point)
{
point.X /= Graphics.PrimaryScreenWidthInPixels;
point.Y /= Graphics.PrimaryScreenHeightInPixels;
//point within regions.Last(); and not within a deadzone
return (regions.Last().Contains(point.X, point.Y))
&& !(deadzones != null && deadzones.Any() && deadzones.Exists(x => x.Contains(point.X, point.Y)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ public SegmentScaling(int n, float innerRadius, float outerRadius, double scale=
// To make sure things don't get stretched, we scale to the smaller axis
// which makes things spherical in the centre, and extend beyond 1 outside
screenScale = Math.Min(Graphics.PrimaryScreenHeightInPixels, Graphics.PrimaryScreenWidthInPixels)/2;
}
}

public List<Point> GetContours()
public List<Region> GetContours()
{
List<Point> ctrs = new List<Point>();
ctrs.Add(new Point(screenScale * innerRadius, screenScale * innerRadius));
ctrs.Add(new Point(screenScale * outerRadius, screenScale * outerRadius));

return ctrs;
return new List<Region>()
{
new Region(.5 - innerRadius, .5 - innerRadius * Graphics.PrimaryScreenWidthInPixels / Graphics.PrimaryScreenHeightInPixels, 2 * innerRadius, 2 * innerRadius * Graphics.PrimaryScreenWidthInPixels / Graphics.PrimaryScreenHeightInPixels, 2 * innerRadius),
new Region(.5 - outerRadius, .5 - outerRadius * Graphics.PrimaryScreenWidthInPixels / Graphics.PrimaryScreenHeightInPixels, 2 * outerRadius, 2 * outerRadius * Graphics.PrimaryScreenWidthInPixels / Graphics.PrimaryScreenHeightInPixels, 2 * outerRadius)
};
}


Expand Down Expand Up @@ -69,6 +69,8 @@ public Vector CalculateScaling(Point current, Point centre)

// Map back to x, y
return new Vector(scale * Math.Cos(theta_snap), scale * Math.Sin(theta_snap));
}
}

public bool Contains(Point point) { return true; }
}
}
Loading