-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
182 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using UnityEngine; | ||
|
||
// The cluster class represents a collection of points with a defined centroid. | ||
public class Cluster { | ||
// Centroid of the cluster. | ||
private Vector3 centroid = Vector3.zero; | ||
|
||
// List of points in the cluster. | ||
private List<Vector3> points = new List<Vector3>(); | ||
|
||
// Get the list of points. | ||
public IReadOnlyList<Vector3> Points { | ||
get { return points; } | ||
} | ||
|
||
// Return the size of the cluster. | ||
public int Size() { | ||
return points.Count; | ||
} | ||
|
||
// Check whether the cluster is empty. | ||
public bool IsEmpty() { | ||
return Size() == 0; | ||
} | ||
|
||
// Calculate the radius of the cluster. | ||
public float Radius() { | ||
if (IsEmpty()) { | ||
return 0; | ||
} | ||
|
||
Vector3 centroid = Centroid(); | ||
return points.Max(point => Vector3.Distance(centroid, point)); | ||
} | ||
|
||
// Calculate the centroid of the cluster. | ||
public Vector3 Centroid() { | ||
if (IsEmpty()) { | ||
return Vector3.zero; | ||
} | ||
|
||
Vector3 centroid = Vector3.zero; | ||
foreach (var point in points) { | ||
centroid += point; | ||
} | ||
centroid /= points.Count; | ||
return centroid; | ||
} | ||
|
||
// Recenter the cluster's centroid to be the mean of all points in the cluster. | ||
public void Recenter() { | ||
centroid = Centroid(); | ||
} | ||
|
||
// Add a point to the cluster. | ||
// This function does not update the centroid of the cluster. | ||
public void AddPoint(in Vector3 point) { | ||
points.Add(point); | ||
} | ||
|
||
// Add multiple points to the cluster. | ||
// This function does not update the centroid of the cluster. | ||
public void AddPoints(in IReadOnlyList<Vector3> otherPoints) { | ||
points.AddRange(otherPoints); | ||
} | ||
|
||
// Merge another cluster into this one. | ||
// This function does not update the centroid of the cluster. | ||
public void Merge(in Cluster cluster) { | ||
AddPoints(cluster.Points); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
using NUnit.Framework; | ||
using UnityEngine; | ||
using UnityEngine.TestTools; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
|
||
public class ClusterTest { | ||
public static Cluster GenerateCluster(in IReadOnlyList<Vector3> points) { | ||
Cluster cluster = new Cluster(); | ||
cluster.AddPoints(points); | ||
cluster.Recenter(); | ||
return cluster; | ||
} | ||
|
||
[Test] | ||
public void TestSize() { | ||
const int size = 10; | ||
List<Vector3> points = new List<Vector3>(); | ||
for (int i = 0; i < size; ++i) { | ||
points.Add(new Vector3(0, i, 0)); | ||
} | ||
Cluster cluster = GenerateCluster(points); | ||
Assert.AreEqual(cluster.Size(), size); | ||
} | ||
|
||
[Test] | ||
public void TestIsEmpty() { | ||
Cluster emptyCluster = new Cluster(); | ||
Assert.IsTrue(emptyCluster.IsEmpty()); | ||
|
||
Cluster cluster = new Cluster(); | ||
cluster.AddPoint(new Vector3(1, -1, 0)); | ||
Assert.IsFalse(cluster.IsEmpty()); | ||
} | ||
|
||
[Test] | ||
public void TestRadius() { | ||
const float radius = 5; | ||
List<Vector3> points = new List<Vector3> { | ||
new Vector3(0, radius, 0), | ||
new Vector3(0, -radius, 0), | ||
}; | ||
Cluster cluster = GenerateCluster(points); | ||
Assert.AreEqual(cluster.Radius(), radius); | ||
} | ||
|
||
[Test] | ||
public void TestCentroid() { | ||
const float radius = 3; | ||
List<Vector3> points = new List<Vector3>(); | ||
for (int i = -1; i <= 1; ++i) { | ||
for (int j = -1; j <= 1; ++j) { | ||
points.Add(new Vector3(i, j, 0)); | ||
} | ||
} | ||
Cluster cluster = GenerateCluster(points); | ||
Assert.AreEqual(cluster.Centroid(), Vector3.zero); | ||
} | ||
|
||
[Test] | ||
public void TestRecenter() { | ||
const float radius = 3; | ||
List<Vector3> points = new List<Vector3>(); | ||
for (int i = -1; i <= 1; ++i) { | ||
for (int j = -1; j <= 1; ++j) { | ||
points.Add(new Vector3(i, j, 0)); | ||
} | ||
} | ||
Cluster cluster = GenerateCluster(points); | ||
cluster.AddPoint(new Vector3(10, -10, 0)); | ||
cluster.Recenter(); | ||
Assert.AreEqual(cluster.Centroid(), new Vector3(1, -1, 0)); | ||
} | ||
|
||
[Test] | ||
public void TestMerge() { | ||
const int size = 10; | ||
List<Vector3> points1 = new List<Vector3>(); | ||
List<Vector3> points2 = new List<Vector3>(); | ||
for (int i = 0; i < size; ++i) { | ||
points1.Add(new Vector3(0, i, 0)); | ||
points2.Add(new Vector3(i, 0, 0)); | ||
} | ||
Cluster cluster1 = GenerateCluster(points1); | ||
Cluster cluster2 = GenerateCluster(points2); | ||
int size1 = cluster1.Size(); | ||
int size2 = cluster2.Size(); | ||
Vector3 centroid1 = cluster1.Centroid(); | ||
Vector3 centroid2 = cluster2.Centroid(); | ||
cluster1.Merge(cluster2); | ||
cluster1.Recenter(); | ||
Assert.AreEqual(cluster1.Size(), size1 + size2); | ||
Assert.AreEqual(cluster1.Centroid(), (centroid1 + centroid2) / 2); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.