-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathReferenceSystem.cs
86 lines (73 loc) · 2.71 KB
/
ReferenceSystem.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using MathNet.Spatial.Euclidean;
using System.Collections.Generic;
using System.Linq;
namespace TangibleTouch
{
public class ReferenceSystem
{
private Dictionary<Point2D, int> _touchpointMap = new Dictionary<Point2D, int> {
{ new Point2D(1, 3), 0x001 },
{ new Point2D(2, 3), 0x002 },
{ new Point2D(0, 2), 0x004 },
{ new Point2D(1, 2), 0x008 },
{ new Point2D(2, 2), 0x010 },
{ new Point2D(3, 2), 0x020 },
{ new Point2D(0, 1), 0x040 },
{ new Point2D(1, 1), 0x080 },
{ new Point2D(2, 1), 0x100 },
{ new Point2D(3, 1), 0x200 },
{ new Point2D(1, 0), 0x400 },
{ new Point2D(2, 0), 0x800 },
};
/// <summary>
/// Gets the origin of the reference system in screen coordinates.
/// </summary>
public Point2D Origin { get; protected set; }
/// <summary>
/// Gets the x-axis of the reference system
/// </summary>
public Vector2D Vx { get; protected set; }
/// <summary>
/// Gets the y-axis of the reference system
/// </summary>
public Vector2D Vy { get; protected set; }
/// <summary>
/// Angle between the reference system and the positive y-axis of the screen.
/// </summary>
public double Angle { get; protected set; }
/// <summary>
/// Holds information about the reference coordinates (origin, vx, vy) and maps arbitrary screen coordinates to touchcodes.
/// </summary>
/// <param name="origin">The origin of the reference system in screen coordinates</param>
/// <param name="vx">The x-axis of the reference system</param>
/// <param name="vy">The y-axis of the reference system</param>
public ReferenceSystem(Point2D origin, Vector2D vx, Vector2D vy)
{
Origin = origin;
Vx = vx;
Vy = vy;
Angle = Vy.SignedAngleTo(new Vector2D(0, 1), false, false).Degrees;
}
/// <summary>
/// Maps a list of TouchPoints in screen coordinates to the reference system coordinates and extracts a Touchcode.
/// </summary>
/// <param name="touchPoints">TouchPoints in screen coordinates</param>
/// <returns>A <see cref="Touchcode"/>instance</returns>
public virtual Touchcode MapPointsToTouchcode(IEnumerable<Point2D> touchPoints)
{
var threshold = 0.2001;
var touchcode = 0;
_touchpointMap
.ToList()
.ForEach(map => touchcode |= touchPoints.Any(tp => Normalize(tp).AlmostEqual(map.Key, threshold)) ? map.Value : 0);
return new Touchcode(touchcode, this.Angle, this.Origin);
}
private Point2D Normalize(Point2D point)
{
var oPoint = point - Origin;
var xcor = Vx.Normalize().DotProduct(oPoint / Vx.Length) * 3;
var ycor = Vy.Normalize().DotProduct(oPoint / Vy.Length) * 3;
return new Point2D(xcor, ycor);
}
}
}