⚽ Player Performance Analyzer — Trajectory Clustering Live
Cluster simulated player movement trajectories with k-means over spatial features, watching tactical role clusters emerge live as a match unfolds.
About this simulation
This analyzer drops a squad of synthetic players onto a pitch, lets simple steering and possession logic drive their movement for a simulated match, and continuously reduces each player's trajectory history down to five tactical features: average field position, roaming coverage area, sprint frequency and pass-network centrality. A real k-means clustering loop — k-means++ seeding, Euclidean assignment, centroid update, repeated to convergence — then groups the squad into tactical roles that update live as the match evolves, rather than following any pre-scripted formation.
🔬 What it shows
A 3D top-down pitch where every player is a real Three.js sphere coloured by its current cluster, bouncing with sprint speed and casting a shadow on the turf. Alongside it, a feature-space scatter plot (rendered via a CanvasTexture-backed plane under an orthographic camera) plots every player's standardized feature vector, with white crosshairs marking each cluster's centroid — the same space the k-means loop actually clusters in.
🎮 How to use
Adjust player count (15–22), the number of tactical clusters k (2–6) and how often the match re-clusters. Toggle the feature-space scatter between Sprint/Coverage and Position/Press-centrality axes, force an immediate re-cluster, change match speed, or start a fresh match with new player archetypes. The side panel lists each cluster's live size and its auto-generated tactical label.
💡 Did you know?
K-means never sees a player's assigned archetype — defenders, wingers, forwards — only the derived numbers. The "High Press", "Deep Block" and "Wide Overlap" labels shown on screen are reverse-engineered after each clustering pass by comparing each cluster's average field position, sprint frequency, coverage and pass centrality against the whole squad's statistics, which is exactly how real sports-analytics teams turn raw tracking data into readable tactical insight.
Frequently asked questions
What is k-means clustering?
K-means is an unsupervised learning algorithm that partitions data points into k groups so that each point belongs to the cluster whose centroid (mean) it is closest to, measured by Euclidean distance. It alternates between an assignment step, where every point joins its nearest centroid, and an update step, where each centroid moves to the mean of the points assigned to it, repeating until the assignments stop changing or the centroids barely move.
Why cluster tactical features instead of raw player positions?
Raw x,y coordinates only describe where a player is at one instant, which is dominated by whichever phase of play is happening right now. Deriving features from the trajectory history — average field position, roaming coverage area, sprint frequency and pass-network centrality — captures how a player behaves over time, which is what actually distinguishes tactical roles such as a high press forward from a deep-lying defender, even when their instantaneous positions briefly overlap.
What does k-means++ initialisation do and why does it matter?
Plain k-means picks starting centroids uniformly at random, which can produce poor clusters or slow convergence if two initial centroids land close together. K-means++ instead picks the first centroid randomly, then chooses each subsequent centroid with probability proportional to its squared distance from the nearest centroid already chosen, spreading the initial seeds out across the data. This nearly always produces faster convergence and a lower final inertia than naive random initialisation.
What is inertia (WCSS) and why does it matter here?
Inertia, or within-cluster sum of squares, is the total squared Euclidean distance between every point and its assigned cluster centroid, computed in the standardized feature space. Lower inertia means tighter, more internally consistent clusters. Watching inertia drop across the assignment/update iterations each time the match re-clusters shows the algorithm actually converging, rather than just re-colouring dots at random.
How are the tactical role names like "High Press" or "Deep Block" chosen?
K-means itself only outputs numbered clusters — it has no idea what a "deep block" is. After each clustering pass, the simulation looks at each cluster's average raw feature values relative to the whole squad's statistics that pass, and applies simple, transparent rules to attach a human-readable tactical label, so cluster 2 today might read as "Wide Overlap" while cluster 2 tomorrow reads as "High Press" if the underlying players' behaviour has shifted.
Cluster simulated player movement trajectories with k-means over spatial features, watching tactical role clusters emerge live as a match unfolds.
3D · Three.js / WebGL renderer · 60 FPS target · runs fully client-side, no install