123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- // 定义雷达坐标系中的矩形接口
- export interface RadarRect {
- x_cm_start: number
- x_cm_stop: number
- y_cm_start: number
- y_cm_stop: number
- }
- // 定义画布坐标系中的矩形接口
- export interface CanvasRect {
- left: number
- top: number
- width: number
- height: number
- }
- // 定义雷达在画布中的位置接口
- export interface RadarPosition {
- x_radar: number
- y_radar: number
- }
- // 定义家具在雷达坐标系中的接口
- export interface RadarFurniture {
- x: number
- y: number
- width: number
- height: number
- }
- /**
- * 检测区域、子区域 矩形转换 雷达坐标系 --> 画布坐标系
- * @param src_rect - 雷达坐标系矩形
- * @param p_radar - 画布中雷达的位置
- * @returns CSS 可用矩形
- */
- export function convert_region_r2c(src_rect: RadarRect, p_radar: RadarPosition): CanvasRect {
- const x_radar = p_radar.x_radar
- const y_radar = p_radar.y_radar
- const left = x_radar + src_rect.x_cm_start
- const top = y_radar - src_rect.y_cm_stop
- const width = src_rect.x_cm_stop - src_rect.x_cm_start
- const height = src_rect.y_cm_stop - src_rect.y_cm_start
- return { left, top, width, height }
- }
- /**
- * 检测区域、子区域 矩形转换 画布坐标系 --> 雷达坐标系
- * @param dst_rect - 画布矩形
- * @param p_radar - 雷达在画布坐标系中的位置
- * @returns 雷达坐标矩形
- */
- export function convert_region_c2r(dst_rect: CanvasRect, p_radar: RadarPosition): RadarRect {
- const x_radar = p_radar.x_radar
- const y_radar = p_radar.y_radar
- const x_cm_start = dst_rect.left - x_radar
- const x_cm_stop = x_cm_start + dst_rect.width
- const y_cm_stop = y_radar - dst_rect.top
- const y_cm_start = y_cm_stop - dst_rect.height
- return {
- x_cm_start,
- x_cm_stop,
- y_cm_start,
- y_cm_stop,
- }
- }
- /**
- * 家具 矩形转换 雷达坐标系 --> 画布坐标系
- * @param furniture - 雷达坐标家具对象
- * @param p_radar - 雷达在画布上的坐标
- * @returns CSS 可用家具矩形
- */
- export function convert_furniture_r2c(
- furniture: RadarFurniture,
- p_radar: RadarPosition
- ): CanvasRect {
- const x_radar = p_radar.x_radar
- const y_radar = p_radar.y_radar
- const left = x_radar + furniture.x
- const top = y_radar - furniture.y
- const width = furniture.width
- const height = furniture.height
- return {
- left,
- top,
- width,
- height,
- }
- }
- /**
- * 家具 矩形转换 画布坐标系 --> 雷达坐标系
- * @param furniture_item - 画布矩形(CSS)
- * @param p_radar - 雷达在画布上的坐标
- * @returns 雷达坐标家具矩形
- */
- export function convert_furniture_c2r(
- furniture_item: CanvasRect,
- p_radar: RadarPosition
- ): RadarFurniture {
- const x_radar = p_radar.x_radar
- const y_radar = p_radar.y_radar
- const x = furniture_item.left - x_radar
- const y = y_radar - furniture_item.top
- const width = furniture_item.width
- const height = furniture_item.height
- return {
- x,
- y,
- width,
- height,
- }
- }
- /* ===================== 旋转方法 =================================== */
- interface Rect {
- left: number
- top: number
- width: number
- height: number
- }
- interface Point {
- x: number
- y: number
- }
- /**
- * 顺时针旋转矩形
- * @param src_rect - 输入矩形 { left, top, width, height }
- * @param pRadar - 雷达中心坐标 { x, y }
- * @param angle - 顺时针旋转角度 0, 90, 180, 270
- * @returns 旋转后的矩形 { left, top, width, height }
- */
- export function rotateRect_cw(src_rect: Rect, pRadar: Point, angle: number): Rect {
- if (![0, 90, 180, 270].includes(angle)) angle = 0
- const { left, top, width, height } = src_rect
- const cx = left + width / 2
- const cy = top + height / 2
- const dx = cx - pRadar.x
- const dy = cy - pRadar.y
- let new_dx: number = 0
- let new_dy: number = 0
- switch (angle) {
- case 0:
- new_dx = dx
- new_dy = dy
- break
- case 90:
- new_dx = -dy
- new_dy = dx
- break
- case 180:
- new_dx = -dx
- new_dy = -dy
- break
- case 270:
- new_dx = dy
- new_dy = -dx
- break
- }
- const new_cx = pRadar.x + new_dx
- const new_cy = pRadar.y + new_dy
- let new_width = width
- let new_height = height
- if (angle === 90 || angle === 270) {
- new_width = height
- new_height = width
- }
- return {
- left: new_cx - new_width / 2,
- top: new_cy - new_height / 2,
- width: new_width,
- height: new_height,
- }
- }
- /**
- * 逆时针旋转矩形(家具/检测区域)
- * @param src_rect - 输入矩形 { left, top, width, height }
- * @param pRadar - 雷达中心坐标 { x, y }
- * @param angle - 逆时针旋转角度 0, 90, 180, 270
- * @returns 旋转后的矩形 { left, top, width, height }
- */
- export function rotateRect_ccw(src_rect: Rect, pRadar: Point, angle: number): Rect {
- if (![0, 90, 180, 270].includes(angle)) angle = 0
- const { left, top, width, height } = src_rect
- const cx = left + width / 2
- const cy = top + height / 2
- const dx = cx - pRadar.x
- const dy = cy - pRadar.y
- let new_dx: number = 0
- let new_dy: number = 0
- switch (angle) {
- case 0:
- new_dx = dx
- new_dy = dy
- break
- case 90:
- new_dx = dy
- new_dy = -dx
- break
- case 180:
- new_dx = -dx
- new_dy = -dy
- break
- case 270:
- new_dx = -dy
- new_dy = dx
- break
- }
- const new_cx = pRadar.x + new_dx
- const new_cy = pRadar.y + new_dy
- let new_width = width
- let new_height = height
- if (angle === 90 || angle === 270) {
- new_width = height
- new_height = width
- }
- return {
- left: new_cx - new_width / 2,
- top: new_cy - new_height / 2,
- width: new_width,
- height: new_height,
- }
- }
- interface Point {
- x: number
- y: number
- }
- /**
- * 将雷达坐标系中的点转换到画布坐标系(旋转 + 平移)
- * @param src_point - 雷达坐标系中的点
- * @param pRadar - 雷达在画布坐标系中的坐标
- * @param angle - 雷达顺时针旋转角度(度)
- * @returns 画布坐标系中的点
- */
- export function convert_point_r2c(src_point: Point, pRadar: Point, angle: number): Point {
- const rad = (angle * Math.PI) / 180 // 角度转弧度(顺时针为正)
- const cosA = Math.cos(rad)
- const sinA = Math.sin(rad)
- // 顺时针旋转
- const xRot = src_point.x * cosA + src_point.y * sinA
- const yRot = -src_point.x * sinA + src_point.y * cosA
- // 平移到画布坐标系
- return {
- x: pRadar.x + xRot,
- y: pRadar.y - yRot,
- }
- }
|