Files
Pier_v1/도면작성/component-dimensions.ts
T
2026-11-04 13:34:51 +09:00

46 lines
3.2 KiB
TypeScript

import type { PierModel } from '../src/core/geometry';
import { entityBounds, localPoint, projectPoint } from './projection';
import type { Entity, Point, ViewId } from './types';
export function componentDimensions(model:PierModel,id:ViewId,geometry:Entity[],scale:number):Entity[]{
const out:Entity[]=[],source={member:'annotation',index:0,pier:model.name};
const dim=(a:Point,b:Point,position:number,axis:'x'|'y')=>{const value=Math.abs(axis==='x'?a[0]-b[0]:a[1]-b[1]);if(value>.001)out.push({kind:'dimension',a,b,position,axis,value,height:2*scale,layer:'DIMENSION',source});};
const coping=geometry.filter(e=>e.source.member==='coping');
if(coping.length&&['front','side'].includes(id)){
const c=entityBounds(coping);dim([c.minX,c.maxY],[c.maxX,c.maxY],c.maxY+5*scale,'x');
const points=coping.flatMap(e=>e.kind==='line'?[e.a,e.b]:e.kind==='polyline'?e.points:[]);
const end=points.filter(p=>Math.abs(p[1]-model.endBottom*1000)<.01).sort((a,b)=>a[0]-b[0])[0];
const level=points.filter(p=>Math.abs(p[1]-model.levelBottom*1000)<.01).sort((a,b)=>a[0]-b[0])[0];
if(end&&level)dim(level,end,c.minX-9*scale,'y');
const top=end?points.filter(p=>Math.abs(p[0]-end[0])<.01&&p[1]>end[1]).sort((a,b)=>b[1]-a[1])[0]:undefined;
if(end&&top)dim(end,top,c.minX-9*scale,'y');
model.columns.forEach((col,i)=>{const p=projectPoint(model,localPoint(model,col.k,col.s,col.bottom,0),id),r=col.diameter*500;
dim([p[0]-r,p[1]+col.diameter*450],[p[0]+r,p[1]+col.diameter*450],p[1]+col.diameter*450,'x');
if(i)dim([p[0]+r,col.bottom*1000],[p[0]+r,col.top*1000],p[0]+r+3*scale,'y');
});
}
if(['front','side','footing'].includes(id))for(let i=0;i<model.footings.length;i++){
const f=geometry.filter(e=>e.source.member==='footing'&&e.source.index===i);if(!f.length)continue;const b=entityBounds(f);
dim([b.minX,b.maxY],[b.maxX,b.maxY],b.maxY+(id==='footing'?4:1)*scale,'x');
if(id==='footing')dim([b.maxX,b.minY],[b.maxX,b.maxY],b.maxX+5*scale,'y');
}
if(id==='top'){
const b=entityBounds(coping);
for(const row of ['전열','후열']){
const ps=model.bearings.filter(p=>p.row===row).map(p=>projectPoint(model,localPoint(model,p.k,p.s,p.z,p.n),'top')).sort((a,b)=>a[0]-b[0]);if(!ps.length)continue;
const above=ps.reduce((s,p)=>s+p[1],0)/ps.length>(b.minY+b.maxY)/2,position=above?b.maxY+12*scale:b.minY-12*scale;
dim([b.minX,ps[0][1]],ps[0],position,'x');dim(ps[ps.length-1],[b.maxX,ps[ps.length-1][1]],position,'x');
}
const front=model.bearings.find(p=>p.row==='전열'),back=model.bearings.find(p=>p.row==='후열');
if(front&&back){const a=projectPoint(model,localPoint(model,front.k,front.s,front.z,front.n),'top'),c=projectPoint(model,localPoint(model,back.k,back.s,back.z,back.n),'top');dim(a,c,b.maxX+5*scale,'y');}
}
if(id==='footing'&&model.piles.length){
const ps=model.piles.map(p=>projectPoint(model,localPoint(model,p.k,p.s,0,p.n),'footing')),b=entityBounds(geometry);
const unique=(values:number[])=>[...new Set(values.map(n=>Math.round(n*1000)/1000))].sort((a,b)=>a-b);
const xs=unique(ps.map(p=>p[0])),ys=unique(ps.map(p=>p[1]));
xs.slice(1).forEach((x,i)=>dim([xs[i],b.minY],[x,b.minY],b.minY-14*scale,'x'));
ys.slice(1).forEach((y,i)=>dim([b.minX,ys[i]],[b.minX,y],b.minX-11*scale,'y'));
}
return out;
}