php项目统计斜长传精准度如何?

wen PHP项目 2

PHP项目统计斜长传精准度方案

斜长传(Cross-field long pass / Diagonal long ball)的精准度统计,核心是判定传球是否成功到达目标区域/队友脚下,下面给出完整的设计思路和 PHP 实现。

php项目统计斜长传精准度如何?

指标定义

指标 说明
斜长传次数 起点到终点距离 ≥ 30m 且角度在 25°~65° 之间的传球
成功斜长传 传球后接球队友成功控球(未被对手拦截/出界)
精准度 成功次数 / 总次数 × 100%
落点偏差 实际落点与目标点距离(可选,用于精细化)

数据模型

CREATE TABLE passes (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    match_id INT NOT NULL,
    player_id INT NOT NULL,
    team_id INT NOT NULL,
    start_x DECIMAL(6,2),   -- 场地坐标(米)
    start_y DECIMAL(6,2),
    end_x DECIMAL(6,2),
    end_y DECIMAL(6,2),
    pass_type ENUM('short','long','cross','diagonal_long') DEFAULT 'short',
    is_success TINYINT(1) DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_match_player (match_id, player_id)
);

核心判定逻辑(PHP)

class DiagonalPassAnalyzer
{
    private const MIN_DISTANCE = 30.0;      // 最小长传距离(米)
    private const MIN_ANGLE    = 25.0;      // 最小角度
    private const MAX_ANGLE    = 65.0;      // 最大角度(相对球场纵轴)
    /**
     * 判断一次传球是否为斜长传
     */
    public function isDiagonalLongPass(array $pass): bool
    {
        $dx = $pass['end_x'] - $pass['start_x'];
        $dy = $pass['end_y'] - $pass['start_y'];
        $distance = sqrt($dx * $dx + $dy * $dy);
        if ($distance < self::MIN_DISTANCE) {
            return false;
        }
        // 角度:相对球场纵轴(y 轴)的夹角
        // 用 atan2 求与 y 轴夹角,再转角度
        $angle = rad2deg(atan2(abs($dx), abs($dy)));
        return $angle >= self::MIN_ANGLE && $angle <= self::MAX_ANGLE;
    }
    /**
     * 统计某球员斜长传精准度
     */
    public function playerAccuracy(PDO $pdo, int $playerId, ?int $matchId = null): array
    {
        $sql = "SELECT start_x, start_y, end_x, end_y, is_success
                FROM passes WHERE player_id = :pid";
        $params = [':pid' => $playerId];
        if ($matchId !== null) {
            $sql .= " AND match_id = :mid";
            $params[':mid'] = $matchId;
        }
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $total = 0;
        $success = 0;
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            if (!$this->isDiagonalLongPass($row)) {
                continue;
            }
            $total++;
            if ((int)$row['is_success'] === 1) {
                $success++;
            }
        }
        return [
            'player_id'  => $playerId,
            'total'      => $total,
            'success'    => $success,
            'accuracy'   => $total > 0 ? round($success / $total * 100, 2) : 0.0,
        ];
    }
}

SQL 版批量统计(性能更好)

如果不想逐条在 PHP 里算,可用 SQL 直接聚合:

SELECT
    player_id,
    COUNT(*) AS total,
    SUM(is_success) AS success,
    ROUND(SUM(is_success) / COUNT(*) * 100, 2) AS accuracy
FROM passes
WHERE match_id = ?
  AND SQRT(POW(end_x - start_x, 2) + POW(end_y - start_y, 2)) >= 30
  AND DEGREES(ATAN2(ABS(end_x - start_x), ABS(end_y - start_y))) BETWEEN 25 AND 65
GROUP BY player_id
ORDER BY accuracy DESC;

注意:POW/ATAN2/DEGREES 在 MySQL、PostgreSQL 都支持,PostgreSQL 需改用 power、atan2(或 atan(y,x))、degrees。

进阶:落点精度评价

如果数据里有目标点和实际落点,可量化精准度而非简单二值:

public function landingDeviation(array $pass): float
{
    $dx = $pass['actual_x'] - $pass['target_x'];
    $dy = $pass['actual_y'] - $pass['target_y'];
    return sqrt($dx * $dx + $dy * $dy); // 米
}
// 可定义等级
// < 3m 优秀,3-8m 良好,8-15m 一般,>15m 失误

数据来源建议

  1. GPS/光学追踪数据(StatsBomb、Opta、Tracab)—— 最准确,提供坐标和接球归属。
  2. 事件流 JSON 导入 —— 建立 ETL 将事件转为 passes 表。
  3. 手动标注 —— 适合业余球队,提供简易录入页面。

图表展示

  • 用 Chart.js / ECharts 展示球员斜长传热力图(起点-终点连线)
  • 累计精准度趋势折线图
  • 队内排行榜
// 简单接口输出 JSON 给前端
header('Content-Type: application/json');
echo json_encode((new DiagonalPassAnalyzer())->playerAccuracy($pdo, 7));

关键点提示

  • 角度定义要和你的场地坐标系一致(这里假设 y 轴为球场长度方向)。
  • 斜长传的阈值(30m / 25°-65°)需按联赛水平校准,青训和成人队标准不同。
  • "成功"定义很关键:是被本方接到,还是未被对方拦截?建议以接球为准。
  • 大量数据建议预计算,把判别结果写入 is_diagonal_long 字段并加索引,避免实时 SQRT/POW。

如果你能说明数据字段(是否有接球人、目标点、坐标单位)和数据库类型,我可以给出更贴合的 schema 和查询。

友情链接

欧易欧易欧易欧易欧易欧易欧易欧易

抱歉,评论功能暂时关闭!

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝