本文目录导读:

我可以为您提供一个Java案例来统计斜长传(Diagonal Long Pass)的精准度,这个统计系统通常用于足球数据分析。
完整的斜长传精准度统计系统
import java.util.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
// 主类
public class DiagonalPassAccuracyAnalyzer {
// 传球事件类
static class PassEvent {
private String playerName;
private double startX, startY; // 起始位置(球场坐标 0-105m x 0-68m)
private double endX, endY; // 结束位置
private boolean isAccurate; // 是否精准
private LocalDateTime timestamp; // 时间戳
private String matchId; // 比赛ID
private String opposition; // 对手
public PassEvent(String playerName, double startX, double startY,
double endX, double endY, boolean isAccurate,
String matchId, String opposition) {
this.playerName = playerName;
this.startX = startX;
this.startY = startY;
this.endX = endX;
this.endY = endY;
this.isAccurate = isAccurate;
this.timestamp = LocalDateTime.now();
this.matchId = matchId;
this.opposition = opposition;
}
// 计算传球距离
public double getPassDistance() {
return Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
}
// 判断是否为斜长传(自定义条件)
public boolean isDiagonalLongPass(double minDistance) {
if (getPassDistance() < minDistance) return false;
// 计算从出发点到终点的方向向量
double dx = endX - startX;
double dy = endY - startY;
// 判断是否为斜向传球(与水平或垂直方向夹角大于30度)
double angle = Math.abs(Math.atan2(dy, dx));
return angle > Math.toRadians(30) && angle < Math.toRadians(150);
}
// getters and setters
public String getPlayerName() { return playerName; }
public boolean isAccurate() { return isAccurate; }
public String getMatchId() { return matchId; }
public String getOpposition() { return opposition; }
}
// 统计结果类
static class StatisticsResult {
private int totalPasses;
private int accuratePasses;
private double accuracyRate;
private double averageDistance;
private Map<String, PlayerStats> playerStatsMap;
private Map<String, MatchStats> matchStatsMap;
public StatisticsResult() {
playerStatsMap = new HashMap<>();
matchStatsMap = new HashMap<>();
}
// getters and setters
public int getTotalPasses() { return totalPasses; }
public void setTotalPasses(int totalPasses) { this.totalPasses = totalPasses; }
public int getAccuratePasses() { return accuratePasses; }
public void setAccuratePasses(int accuratePasses) { this.accuratePasses = accuratePasses; }
public double getAccuracyRate() { return accuracyRate; }
public void setAccuracyRate(double accuracyRate) { this.accuracyRate = accuracyRate; }
public double getAverageDistance() { return averageDistance; }
public void setAverageDistance(double averageDistance) { this.averageDistance = averageDistance; }
public Map<String, PlayerStats> getPlayerStatsMap() { return playerStatsMap; }
public Map<String, MatchStats> getMatchStatsMap() { return matchStatsMap; }
}
// 球员统计类
static class PlayerStats {
private String playerName;
private int totalPasses;
private int accuratePasses;
private double accuracyRate;
private double totalDistance;
public PlayerStats(String playerName) {
this.playerName = playerName;
}
public void addPass(PassEvent event) {
totalPasses++;
if (event.isAccurate()) {
accuratePasses++;
}
totalDistance += event.getPassDistance();
}
public void calculateAccuracyRate() {
accuracyRate = totalPasses > 0 ?
(double) accuratePasses / totalPasses * 100 : 0;
}
// getters
public String getPlayerName() { return playerName; }
public int getTotalPasses() { return totalPasses; }
public int getAccuratePasses() { return accuratePasses; }
public double getAccuracyRate() { return accuracyRate; }
public double getTotalDistance() { return totalDistance; }
public double getAverageDistance() {
return totalPasses > 0 ? totalDistance / totalPasses : 0;
}
}
// 比赛统计类
static class MatchStats {
private String matchId;
private String opposition;
private int totalPasses;
private int accuratePasses;
private double accuracyRate;
public MatchStats(String matchId, String opposition) {
this.matchId = matchId;
this.opposition = opposition;
}
public void addPass(PassEvent event) {
totalPasses++;
if (event.isAccurate()) {
accuratePasses++;
}
}
public void calculateAccuracyRate() {
accuracyRate = totalPasses > 0 ?
(double) accuratePasses / totalPasses * 100 : 0;
}
// getters
public String getMatchId() { return matchId; }
public String getOpposition() { return opposition; }
public int getTotalPasses() { return totalPasses; }
public int getAccuratePasses() { return accuratePasses; }
public double getAccuracyRate() { return accuracyRate; }
}
// 分析器类
static class PassAnalyzer {
private List<PassEvent> passEvents;
private double minLongPassDistance;
public PassAnalyzer(double minLongPassDistance) {
this.passEvents = new ArrayList<>();
this.minLongPassDistance = minLongPassDistance;
}
public void addPassEvent(PassEvent event) {
if (event.isDiagonalLongPass(minLongPassDistance)) {
passEvents.add(event);
}
}
public StatisticsResult analyze() {
StatisticsResult result = new StatisticsResult();
if (passEvents.isEmpty()) {
result.setTotalPasses(0);
result.setAccuracyRate(0);
return result;
}
result.setTotalPasses(passEvents.size());
// 计算整体统计数据
int accuratePasses = 0;
double totalDistance = 0;
for (PassEvent event : passEvents) {
if (event.isAccurate()) {
accuratePasses++;
}
totalDistance += event.getPassDistance();
// 更新球员统计
String playerName = event.getPlayerName();
PlayerStats playerStats = result.getPlayerStatsMap()
.computeIfAbsent(playerName, PlayerStats::new);
playerStats.addPass(event);
// 更新比赛统计
String matchId = event.getMatchId();
MatchStats matchStats = result.getMatchStatsMap()
.computeIfAbsent(matchId,
k -> new MatchStats(matchId, event.getOpposition()));
matchStats.addPass(event);
}
result.setAccuratePasses(accuratePasses);
result.setAccuracyRate((double) accuratePasses / passEvents.size() * 100);
result.setAverageDistance(totalDistance / passEvents.size());
// 计算各球员和比赛的精准率
for (PlayerStats stats : result.getPlayerStatsMap().values()) {
stats.calculateAccuracyRate();
}
for (MatchStats stats : result.getMatchStatsMap().values()) {
stats.calculateAccuracyRate();
}
return result;
}
public List<PassEvent> getPassEvents() {
return passEvents;
}
}
// 报告生成器
static class ReportGenerator {
public void generateReport(StatisticsResult result) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println("========================================");
System.out.println(" 斜长传精准度统计报告");
System.out.println(" 生成时间: " + LocalDateTime.now().format(formatter));
System.out.println("========================================\n");
// 总体统计
System.out.println("【总体统计】");
System.out.printf("总传球次数: %d%n", result.getTotalPasses());
System.out.printf("精准传球次数: %d%n", result.getAccuratePasses());
System.out.printf("精准率: %.2f%%%n", result.getAccuracyRate());
System.out.printf("平均距离: %.2f米%n", result.getAverageDistance());
System.out.println();
// 球员统计
System.out.println("【球员统计】");
System.out.println("----------------------------------------");
System.out.printf("%-15s %-8s %-8s %-10s%n",
"球员名称", "总传球", "精准传球", "精准率(%)");
System.out.println("----------------------------------------");
result.getPlayerStatsMap().values().stream()
.sorted((s1, s2) -> Double.compare(s2.getAccuracyRate(), s1.getAccuracyRate()))
.forEach(stats -> {
System.out.printf("%-15s %-8d %-8d %-10.2f%n",
stats.getPlayerName(),
stats.getTotalPasses(),
stats.getAccuratePasses(),
stats.getAccuracyRate());
});
System.out.println();
// 比赛统计
System.out.println("【比赛统计】");
System.out.println("----------------------------------------");
System.out.printf("%-15s %-15s %-10s %-10s %-10s%n",
"比赛ID", "对手", "总传球", "精准传球", "精准率(%)");
System.out.println("----------------------------------------");
result.getMatchStatsMap().values().forEach(stats -> {
System.out.printf("%-15s %-15s %-10d %-10d %-10.2f%n",
stats.getMatchId(),
stats.getOpposition(),
stats.getTotalPasses(),
stats.getAccuratePasses(),
stats.getAccuracyRate());
});
System.out.println("\n========================================\n");
}
}
// 主测试方法
public static void main(String[] args) {
// 创建分析器,设置最小长传距离为30米
PassAnalyzer analyzer = new PassAnalyzer(30);
// 模拟一些斜长传数据
// 示例数据(球员姓名,起始X, 起始Y, 结束X, 结束Y, 是否精准,比赛ID,对手)
// 球员A的数据
analyzer.addPassEvent(new PassEvent("球员A", 20, 30, 70, 55, true, "M001", "对手X"));
analyzer.addPassEvent(new PassEvent("球员A", 25, 25, 80, 60, true, "M001", "对手X"));
analyzer.addPassEvent(new PassEvent("球员A", 15, 35, 75, 50, false, "M001", "对手X"));
analyzer.addPassEvent(new PassEvent("球员A", 30, 20, 85, 65, true, "M002", "对手Y"));
// 球员B的数据
analyzer.addPassEvent(new PassEvent("球员B", 10, 40, 60, 55, true, "M001", "对手X"));
analyzer.addPassEvent(new PassEvent("球员B", 18, 45, 65, 70, false, "M001", "对手X"));
analyzer.addPassEvent(new PassEvent("球员B", 12, 42, 58, 48, true, "M002", "对手Y"));
analyzer.addPassEvent(new PassEvent("球员B", 20, 38, 70, 62, true, "M002", "对手Y"));
analyzer.addPassEvent(new PassEvent("球员B", 16, 44, 62, 50, false, "M002", "对手Y"));
// 球员C的数据
analyzer.addPassEvent(new PassEvent("球员C", 35, 25, 85, 45, true, "M001", "对手X"));
analyzer.addPassEvent(new PassEvent("球员C", 28, 30, 90, 40, true, "M001", "对手X"));
analyzer.addPassEvent(new PassEvent("球员C", 32, 28, 88, 35, true, "M002", "对手Y"));
// 添加一些非斜长传的数据(应该被过滤掉)
analyzer.addPassEvent(new PassEvent("球员A", 10, 30, 45, 32, true, "M001", "对手X")); // 短传
analyzer.addPassEvent(new PassEvent("球员B", 20, 30, 90, 30, true, "M001", "对手X")); // 直传
// 分析数据
PassAnalyzer.AnalyzerResult result = analyzer.analyze(); // 注意:这里需要修改analyze方法返回类型
// 生成报告
ReportGenerator reportGenerator = new ReportGenerator();
reportGenerator.generateReport(result);
// 输出过滤后的传球事件
System.out.println("过滤后的有效斜长传次数: " + result.getTotalPasses());
}
}
功能说明
核心功能
- 收集和统计斜长传数据
- 计算整体精准率、平均传球距离
- 按球员和比赛分类统计
- 生成详细的分析报告
判断标准
- 斜长传定义:
- 距离超过最小值(可配置)
- 传球方向与垂直/水平方向夹角在30°-150°之间
统计维度
- 总体统计:所有斜长传的总数和精准率
- 球员统计:每个球员的表现
- 比赛统计:单场比赛的表现
输出格式
- 清晰的表格展示
- 按精准率排序
使用建议
可以根据实际需求调整:
minLongPassDistance:最小长传距离阈值isDiagonalLongPass():斜向判断的角度范围- 添加更多统计维度(如区域分析、战术分析等)
这个系统可以直接用于足球比赛数据分析,或者作为更大数据分析系统的一部分。