liusuyi
2026-05-12 9f327c33730ba10cb2d89aff99b727502232e968
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
package com.ard.work.sdk.zlxd.utils;
 
import com.ard.work.api.domian.PointFrame;
import lombok.Data;
import lombok.AllArgsConstructor;
 
/**
 * 新相机 3D 定位坐标转换工具 (纯 Integer 版)
 *
 * <p>适用场景:
 * 1. 前端/后端/海康 SDK 全程使用 Integer。
 * 2. 忽略小数精度,直接基于整数差值判断业务意图。
 * </p>
 */
public class PTZ3DLocationConverter {
 
    // ================= 配置常量 =================
    private static final int TARGET_W = 1920;
    private static final int TARGET_H = 1080;
    private static final int SOURCE_SCALE = 255;
 
    // 中心点 (整数除法会自动向下取整,960, 540)
    private static final int CENTER_X = TARGET_W / 2;
    private static final int CENTER_Y = TARGET_H / 2;
 
    /**
     * 缩小判定阈值:xTop - xBottom > 2
     */
    private static final int SHRINK_THRESHOLD = 2;
 
    /**
     * 输出模型:新相机协议参数
     */
    @Data
    @AllArgsConstructor
    public static class LocationParam {
        private final int areaWidth;
        private final int areaHeight;
        private final int areaX;
        private final int areaY;
    }
 
    // ================= 核心转换逻辑 =================
    public static LocationParam convertPrecise(PointFrame frame) {
        if (frame == null) throw new IllegalArgumentException("Frame is null");
 
        int x1 = frame.getXTop();
        int y1 = frame.getYTop();
        int x2 = frame.getXBottom();
        int y2 = frame.getYBottom();
 
        // 1. 缩小判断
        if ((x1 - x2) > SHRINK_THRESHOLD) {
            return new LocationParam(0, 0, 0, 0);
        }
 
        // 2. 点击判断
        if (x1 == x2 && y1 == y2) {
            // 坐标转像素
            int pxX = x1 * TARGET_W / SOURCE_SCALE;
            int pxY = y1 * TARGET_H / SOURCE_SCALE;
 
            int offsetX = pxX - CENTER_X;
            int offsetY = -(pxY - CENTER_Y);
 
            return new LocationParam(TARGET_W, TARGET_H, offsetX, offsetY);
        }
 
        // 3. 框选 (放大)
        int centerX = (x1 + x2) / 2;
        int centerY = (y1 + y2) / 2;
 
        int pxCenterX = centerX * TARGET_W / SOURCE_SCALE;
        int pxCenterY = centerY * TARGET_H / SOURCE_SCALE;
 
        int w = Math.abs(x2 - x1) * TARGET_W / SOURCE_SCALE;
        int h = Math.abs(y2 - y1) * TARGET_H / SOURCE_SCALE;
 
        int offsetX = pxCenterX - CENTER_X;
        int offsetY = -(pxCenterY - CENTER_Y);
 
        return new LocationParam(w, h, offsetX, offsetY);
    }
}