/**
 * 拓扑连线：锚点坐标、自动选边、正交折线路径
 */
import type { FloorMapEdge, FloorMapEdgeAnchor, FloorMapEdgeRouting, FloorMapItemBase } from '../types';
export interface FloorMapItemPixelRect {
    left: number;
    top: number;
    width: number;
    height: number;
}
export interface FloorMapEdgeRoute {
    edgeId: string;
    points: [number, number][];
    pathD: string;
}
declare const ANCHORS: FloorMapEdgeAnchor[];
/**
 * 将图元逻辑坐标转为内容区像素矩形（与 EditableItemLayer 一致）
 */
export declare function getItemPixelRect<T extends FloorMapItemBase>(item: T, options: {
    cellSize: number;
    itemUnit: 'cell' | 'pixel';
    itemGap?: number;
    override?: Partial<FloorMapItemPixelRect>;
}): FloorMapItemPixelRect;
export declare function rectCenter(rect: FloorMapItemPixelRect): {
    x: number;
    y: number;
};
/**
 * 锚点在矩形边框上的坐标
 */
export declare function getAnchorPoint(rect: FloorMapItemPixelRect, anchor: FloorMapEdgeAnchor): {
    x: number;
    y: number;
};
/** 与 EdgeLayer 端口标签 pill 高度一致 */
export declare const EDGE_PORT_LABEL_HEIGHT = 18;
/** 标签中心相对边框锚点的外移间距（px） */
export declare const EDGE_PORT_LABEL_OFFSET_GAP = 6;
/**
 * 编辑态连线锚点圆点外移距离（px），避开 EditableItemLayer 边中点 20×20 缩放手柄。
 */
export declare const EDGE_PORT_MARKER_OUTSET = 16;
/** 折线绕开图元矩形的间距（px） */
export declare const EDGE_ROUTE_RECT_CLEARANCE = 10;
/**
 * 编辑态锚点圆点 UI 位置（相对图元局部坐标），沿外法线外移，连线几何仍用 {@link getAnchorPoint}。
 */
export declare function getPortMarkerDisplayPoint(rect: FloorMapItemPixelRect, anchor: FloorMapEdgeAnchor, outset?: number): {
    x: number;
    y: number;
};
export declare function getPortLabelPosition(rect: FloorMapItemPixelRect, anchor: FloorMapEdgeAnchor, options?: {
    labelHeight?: number;
    gap?: number;
}): {
    x: number;
    y: number;
};
/** 折线中段连接类型标签相对路径的默认外偏移（px） */
export declare const EDGE_CENTER_LABEL_OFFSET = 8;
export declare type EdgeCenterLabelPlacement = 'middle' | 'target-tail' | 'source-tail' | 'longest-horizontal';
/** 与 EdgeLayer PortLabel 估算宽度一致 */
export declare function estimateEdgeLabelWidth(text: string): number;
/**
 * 在折线指定段上计算标签中心（水平段：标签在线上方；竖直段：标签在线左侧）。
 */
export declare function getEdgeCenterLabelPositionOnSegment(points: [number, number][], segIndex: number, options?: {
    along?: number;
    offsetPx?: number;
    perpOffsetPx?: number;
}): {
    x: number;
    y: number;
} | null;
/**
 * 计算边 `label`（如 connection_type）在正交折线上的显示位置。
 * 默认 `target-tail`：靠近路径末端（目标端），避免标在水平总线中段互相重叠。
 */
export declare function getEdgeCenterLabelPosition(points: [number, number][], options?: {
    placement?: EdgeCenterLabelPlacement;
    offsetPx?: number;
    /** 0–1，沿标签所在段的位置 */
    along?: number;
    /** 垂直于段的额外偏移（水平段：y 方向；竖直段：x 方向，正数向左） */
    perpOffsetPx?: number;
    /** 指定段索引；缺省时由 placement 推导 */
    segIndex?: number;
}): {
    x: number;
    y: number;
} | null;
/** 标签防碰撞：中心点最小间距（px，约等于 pill 高度 + 间距） */
export declare const EDGE_CENTER_LABEL_MIN_GAP = 22;
export interface ResolveEdgeCenterLabelItem {
    edgeId: string;
    sourceId: string;
    targetId: string;
    points: [number, number][];
    label?: string;
}
/**
 * 为多条边的连接类型标签分配互不重叠的位置。
 * - 多边汇入同一目标：优先标在各自「水平总线」段中点（天然错开）
 * - 仍重叠时按 pill 宽高做 bbox 分离；必要时在目标图元左侧纵向堆叠
 */
export declare function resolveEdgeCenterLabelPositions(items: ResolveEdgeCenterLabelItem[], options?: {
    placement?: EdgeCenterLabelPlacement;
    offsetPx?: number;
    rectsById?: Map<string, FloorMapItemPixelRect>;
}): Map<string, {
    x: number;
    y: number;
}>;
/**
 * 未指定锚点时，选朝向对方最近的一侧
 */
export declare function pickAutoAnchor(from: FloorMapItemPixelRect, to: FloorMapItemPixelRect): FloorMapEdgeAnchor;
/** 拉线吸附端口时的命中半径（与 {@link EDGE_PORT_MARKER_OUTSET} 同量级） */
export declare const EDGE_PORT_SNAP_THRESHOLD = 16;
export interface DrawingTargetHit {
    instanceId: string;
    anchor: FloorMapEdgeAnchor;
}
/**
 * 距矩形四边锚点最近的一侧
 */
export declare function pickNearestAnchorOnRect(pt: {
    x: number;
    y: number;
}, rect: FloorMapItemPixelRect): FloorMapEdgeAnchor;
/**
 * 拉线过程中解析目标：优先吸附到端口圆点，否则落在图元内时取最近端口。
 */
export declare function resolveDrawingTargetAtPoint(pt: {
    x: number;
    y: number;
}, instanceIds: string[], rectsById: Map<string, FloorMapItemPixelRect>, excludeInstanceId: string, snapThreshold?: number): DrawingTargetHit | null;
/** 折线是否有线段穿过矩形内部 */
export declare function pathCrossesRectInterior(points: [number, number][], rect: FloorMapItemPixelRect): boolean;
export interface RouteOrthogonalOptions {
    /** 需要绕开的图元矩形（通常为对端节点） */
    obstacleRects?: FloorMapItemPixelRect[];
    clearance?: number;
    /** @deprecated 使用 obstacleRects；保留兼容，等价于 [targetRect] */
    sourceRect?: FloorMapItemPixelRect;
    targetRect?: FloorMapItemPixelRect;
    /**
     * 通道偏移（px，带符号）：用于让多条共享同一通道的连线错开，避免视觉重叠。
     * 影响 Z 型中点（midX/midY）与外侧公共通道（above/below/left/right）。
     */
    channelOffset?: number;
}
/**
 * 正交连线：先最短路径，再对穿框段绕一圈。
 */
export declare function routeOrthogonal(sourcePt: {
    x: number;
    y: number;
}, sourceSide: FloorMapEdgeAnchor, targetPt: {
    x: number;
    y: number;
}, targetSide: FloorMapEdgeAnchor, 
/** @deprecated 已取消固定 stub；可传 number（忽略）或 RouteOrthogonalOptions */
stubOrOptions?: number | RouteOrthogonalOptions, maybeOptions?: RouteOrthogonalOptions): [number, number][];
/**
 * 折线转带圆角的 SVG path d
 */
export declare function pathFromPoints(points: [number, number][], radius?: number): string;
export interface BuildEdgeRouteOptions {
    /** 共享通道时的横向/纵向错位偏移 */
    channelOffset?: number;
    /** 用户手动调整后的路由覆盖；优先于 edge.routing 字段 */
    routingOverride?: FloorMapEdgeRouting;
}
/**
 * 把一条已存在的 path 快照（snapshot）的两端「平移对齐」到新的源/目标锚点位置，
 * 中间路径完全保留。用于「手动编辑过的连线」在图元被拖动后只更新最近两端。
 *
 * 规则：
 * - 首段（snapshot[0] → snapshot[1]）：
 *   - 若是水平段（y0 === y1）：新 snapshot[0] = srcPt；新 snapshot[1] = (原 snapshot[1].x, srcPt.y)
 *   - 若是竖直段（x0 === x1）：新 snapshot[0] = srcPt；新 snapshot[1] = (srcPt.x, 原 snapshot[1].y)
 *   - 若是斜段（理论上 snapshot 都是正交，但兜底）：仅平移 snapshot[0]，snapshot[1] 保持不变
 * - 末段（snapshot[n-2] → snapshot[n-1]）：对称处理
 * - 同时对 snapshot[2] / snapshot[n-3] 做"必要的轴向跟随"：snapshot[1] → snapshot[2] 段必须保持
 *   正交，因此 snapshot[2] 的相邻轴坐标需要跟随 snapshot[1] 更新（同理末端）。
 */
export declare function alignSnapshotToAnchors(snapshot: [number, number][], srcPt: {
    x: number;
    y: number;
}, tgtPt: {
    x: number;
    y: number;
}): [number, number][];
/**
 * 将「中段坐标覆盖」应用到一条正交折线 path 上。
 *
 * 内部段（既非首段也非末段）按顺序对应 `midSegmentPositions[k]`。
 * - 水平段（y1 === y2）→ 把 result[i].y / result[i+1].y 都改成 v
 * - 竖直段（x1 === x2）→ 把 result[i].x / result[i+1].x 都改成 v
 *
 * 移动一个内部段只是平移它的主轴坐标，相邻段（必是另一个方向）会随之延长/缩短，
 * 不会破坏正交性。多余的 override 项被忽略，null/undefined 项跳过。
 */
/** 首/末段拖动后默认插入的 stub 长度（px）；过短时按段长 50% 自动缩小 */
export declare const DEFAULT_EDGE_STUB_LENGTH = 24;
/**
 * 在路径起点处插入 stub 转角：把首段变成「沿首段实际方向走 stub → 90° 转弯 →
 * 走到原 corner」。
 *
 * 注意：方向取自 *path 首段实际指向*（points[0]→points[1]），而非 sourceAnchor 字段——
 * 这样在 path 已经经过手动编辑、首段方向与锚点 outward 不一致时仍能正确插入。
 *
 * 路径点数 +2；新增 2 个内部段（stub 段 + 「被拖动段」）。被拖动段的初始另一轴
 * 坐标与原首段重合（视觉直线），后续由拖动调整。
 */
export declare function applySourceStub(points: [number, number][], stubLength: number | undefined, 
/** @deprecated 仅向后兼容，实际方向由 path 首段决定 */
sourceAnchor?: FloorMapEdgeAnchor): [number, number][];
/**
 * 对称地在路径末端插入 stub 转角。方向取自 *path 末段实际指向*。
 *
 * 路径点数 +2；新增 2 个内部段（「被拖动段」 + stub 段）。
 */
export declare function applyTargetStub(points: [number, number][], stubLength: number | undefined, 
/** @deprecated 仅向后兼容，实际方向由 path 末段决定 */
targetAnchor?: FloorMapEdgeAnchor): [number, number][];
export declare function applyMidSegmentOverrides(points: [number, number][], overrides: (number | null | undefined)[] | undefined): [number, number][];
/**
 * 返回正交折线中所有「内部段」的元信息（不含首段与末段），
 * 供 UI 渲染中段手柄使用。
 */
export interface EdgeInnerSegmentInfo {
    /** 该内部段在 `midSegmentPositions` 中的索引（0 = path 的第 2 段） */
    index: number;
    /** path.points 中该段起点的下标（终点为 i+1） */
    pointIndex: number;
    axis: 'h' | 'v';
    /** 段的主轴坐标：水平段 = y，竖直段 = x */
    position: number;
    /** 段中点坐标（用于摆放手柄） */
    midX: number;
    midY: number;
    /** 段长度（绝对值），用于判定是否值得渲染手柄（防止极短段误触） */
    length: number;
}
export declare function getEdgeInnerSegments(points: [number, number][]): EdgeInnerSegmentInfo[];
export declare function buildEdgeRoute(edge: FloorMapEdge, rectsById: Map<string, FloorMapItemPixelRect>, options?: BuildEdgeRouteOptions): FloorMapEdgeRoute | null;
/**
 * 去掉路径中"三点共线"的冗余中间点（比如 routeOrthogonal 里 srcPt → sOut →
 * 中段折点都在同一 y 上时，sOut 是冗余的）。
 *
 * 保留零长度段：用户拖动 first/last 段创建 stub 时，stubEnd 与 midCorner 短暂
 * 重合（零长度），不能被合并掉，否则会立刻丢失新插入的转角结构。
 */
export declare function simplifyCollinearPath(points: [number, number][]): [number, number][];
/**
 * 按 edge 顺序分配交替偏移，让落到同一通道的多条线错开。
 * 序列：0, +step, -step, +2*step, -2*step, ...
 */
export declare function getEdgeChannelOffset(index: number, step?: number): number;
/** 命中检测：点到折线最近距离 */
export declare function distanceToPolyline(px: number, py: number, points: [number, number][]): number;
export declare function hitTestEdgeAtPoint(px: number, py: number, routes: FloorMapEdgeRoute[], threshold?: number): string | null;
export { ANCHORS as FLOOR_MAP_EDGE_ANCHORS };
