ykzz-web/src/views/Home/zmjk/coordinates.ts

195 lines
6.6 KiB
TypeScript

import { BottomBase, CanvasW, GroundBase, PillarRatio, RoofTop, RoofTopFar, SideRoomSize, ViewCenter } from "./consts";
export type XY = {
x: number;
y: number;
}
export type XYWH = {
x: number;
y: number;
w: number;
h: number;
}
export function intersection(pt1: XY, pt2: XY, result: { x?: number, y?: number }): XY {
const invalid: XY = { x: result.x || 0, y: result.y || 0 };
if (typeof result.x === typeof result.y) {
return invalid;
}
const x1 = pt1.x, y1 = pt1.y, x2 = pt2.x, y2 = pt2.y;
if (typeof result.x === 'number') {
const x3 = result.x;
if (x2 === x1) {
return invalid;
}
result.y = (y2 - y1) * (x3 - x1) / (x2 - x1) + y1;
} else {
const y3 = result.y!;
if (y2 === y1) {
return invalid;
}
result.x = (x2 - x1) * (y3 - y1) / (y2 - y1) + x1;
}
return result as any;
}
export function interpolate(pt1: XY, pt2: XY, ratio: number): XY {
return {
x: pt1.x + (pt2.x - pt1.x) * ratio,
y: pt1.y + (pt2.y - pt1.y) * ratio,
}
}
export function mirror(pt: XY): XY {
return {
x: CanvasW - pt.x,
y: pt.y,
}
}
export type ControlPts = {
C1: XY;
L1: XY;
B1: XY;
C2: XY;
L2: XY;
B2: XY;
A1: XY;
A2: XY;
B3: XY;
RoomLT: XY;
RoomRT: XY;
RoomRB: XY;
RoomLB: XY;
RoomRTFar: XY;
RoomRBFar: XY;
RoomLBFar: XY;
TopRectLB: XY;
TopRectRB: XY;
SepsLTLBRBRT: XY[][];
SepsFront: XYWH[];
SepsFront1: XYWH[];
ZmArea: {
lt0: XY; lt1: XY; lt2: XY; lt3: XY;
lb0: XY; lb1: XY; lb2: XY; lb3: XY;
rt0: XY; rt1: XY; rt2: XY; rt3: XY;
rb0: XY; rb1: XY; rb2: XY; rb3: XY;
}[];
}
export function contextCoordinates(unitWidth: number, hole: number): ControlPts {
const C1 = { x: unitWidth * 0.6, y: GroundBase };
const L1 = { x: unitWidth* 1, y: GroundBase };
const B1 = { x: unitWidth , y: BottomBase }
const C2 = intersection(ViewCenter, C1, { x: 0, y: undefined });
const L2 = intersection(ViewCenter, L1, { x: 0, y: undefined });
const B2 = intersection(ViewCenter, B1, { x: 0, y: undefined });
const A1 = { x: L1.x, y: RoofTop };
const A2 = intersection(ViewCenter, A1, { x: undefined, y: RoofTopFar });
const B3 = intersection(ViewCenter, B2, { x: A2.x, y: undefined })
const RoomLT = { x: (C1.x + L1.x) * 0.5 - SideRoomSize * 0.5, y: RoofTop - SideRoomSize }
const RoomRT = { x: (C1.x + L1.x) * 0.5 + SideRoomSize * 0.5, y: RoofTop - SideRoomSize }
const RoomRB = { x: (C1.x + L1.x) * 0.5 + SideRoomSize * 0.5, y: RoofTop }
const RoomLB = { x: (C1.x + L1.x) * 0.5 - SideRoomSize * 0.5, y: RoofTop }
const RoomRBFar = intersection(ViewCenter, RoomRB, { x: undefined, y: RoofTopFar });
const RoomRTFar = intersection(ViewCenter, RoomRT, { x: RoomRBFar.x, y: undefined });
const RoomLBFar = { x: RoomRBFar.x! - SideRoomSize, y: RoomRBFar.y };
const TopRectLB = interpolate(RoomRB, RoomRBFar, 0.05);
const TopRectRB = mirror(TopRectLB);
const TopHoleLT = intersection(A1, ViewCenter, { x: undefined, y: TopRectLB.y });
const TopHoleRT = mirror(TopHoleLT);
const HolesWidth = TopHoleRT.x - TopHoleLT.x;
const PillarWidth = (HolesWidth / hole) * PillarRatio;
const HoleWidth = (HolesWidth - PillarWidth * (hole - 1)) / hole;
const SepsLTLBRBRT: XY[][] = [];
const SepsFront: XYWH[] = [];
const SepsFront1: XYWH[] = [];
const ZmArea = [];
for (let i = 0; i < hole; i++) {
const TopBase = TopHoleLT.y;
// 隔断
if (i > 0) {
const frontRight1 = TopHoleLT.x + (PillarWidth + HoleWidth) * i;
const frontRight = i == 1 ? TopHoleLT.x + (PillarWidth + HoleWidth) * i + 21 :
i == 2 ? TopHoleLT.x + (PillarWidth + HoleWidth) * i + 18 :
i == 3 ? TopHoleLT.x + (PillarWidth + HoleWidth) * i + 12 :
i == 4 ? TopHoleLT.x + (PillarWidth + HoleWidth) * i + 6 :
i == 5 ? TopHoleLT.x + (PillarWidth + HoleWidth) * i + 1 :
i == 6 ? TopHoleLT.x + (PillarWidth + HoleWidth) * i - 5:
i == 7 ? TopHoleLT.x + (PillarWidth + HoleWidth) * i - 12 :
i == 9 ? TopHoleLT.x + (PillarWidth + HoleWidth) * i - 22 :
i == 8 ? TopHoleLT.x + (PillarWidth + HoleWidth) * i - 15 :
TopHoleLT.x + (PillarWidth + HoleWidth) * i
const frontLeft = frontRight - PillarWidth;
const frontLeft1 = frontRight1 - PillarWidth;
SepsFront.push({ x: frontLeft, y: TopBase, w: PillarWidth, h: BottomBase - TopBase });
SepsFront1.push({ x: frontLeft1, y: TopBase, w: PillarWidth, h: BottomBase - TopBase });
if (i < hole / 2) {
// 右侧面
const p1 = { x: frontRight, y: TopBase };
const p2 = { x: frontRight, y: BottomBase };
const p4 = intersection(p1, ViewCenter, { x: undefined, y: RoofTopFar });
const p3 = intersection(p2, ViewCenter, { x: p4.x, y: undefined });
SepsLTLBRBRT.push([p1, p2, p3, p4]);
} else if (i > hole / 2) {
// 左侧面
const p1 = { x: frontLeft, y: TopBase };
const p2 = { x: frontLeft, y: BottomBase };
const p4 = intersection(p1, ViewCenter, { x: undefined, y: RoofTopFar });
const p3 = intersection(p2, ViewCenter, { x: p4.x, y: undefined });
SepsLTLBRBRT.push([p1, p2, p3, p4]);
}
}
// 闸门面
{
const ZmTopBaseFront = TopBase + 6;
const ZmTopBaseBack = ZmTopBaseFront + 10;
const lt0 = { x: TopHoleLT.x + (PillarWidth + HoleWidth) * i, y: TopBase };
const lb0 = { x: lt0.x, y: BottomBase };
const rb0 = { x: lt0.x + HoleWidth, y: BottomBase };
const lt1 = intersection(ViewCenter, lt0, { x: undefined, y: ZmTopBaseFront });
const lt2 = intersection(ViewCenter, lt0, { x: undefined, y: ZmTopBaseBack });
const lt3 = intersection(ViewCenter, lt0, { x: undefined, y: RoofTopFar });
const lb1 = intersection(ViewCenter, lb0, { x: lt1.x, y: undefined });
const lb2 = intersection(ViewCenter, lb0, { x: lt2.x, y: undefined });
const lb3 = intersection(ViewCenter, lb0, { x: lt3.x, y: undefined });
const rb1 = intersection(ViewCenter, rb0, { x: undefined, y: lb1.y });
const rb2 = intersection(ViewCenter, rb0, { x: undefined, y: lb2.y });
const rb3 = intersection(ViewCenter, rb0, { x: undefined, y: lb3.y });
const rt0 = { x: rb0.x, y: lt0.y };
const rt1 = { x: rb1.x, y: lt1.y };
const rt2 = { x: rb2.x, y: lt2.y };
const rt3 = { x: rb3.x, y: lt3.y };
ZmArea.push({ lt0, lb0, rb0, rt0, lt1, rt1, lb1, rb1, lt2, lb2, rt2, rb2, lt3, lb3, rt3, rb3 });
}
}
return {
C1, L1, B1, C2, L2, B2, A1, A2, B3,
RoomLT, RoomRT, RoomRB, RoomLB, RoomRTFar, RoomRBFar, RoomLBFar,
TopRectLB, TopRectRB,
SepsLTLBRBRT, SepsFront,SepsFront1, ZmArea,
}
}