15 lines
1.6 KiB
TypeScript
15 lines
1.6 KiB
TypeScript
import type { Entity,Point } from './types';
|
|
import { CAD_STYLE } from './cad-style';
|
|
export const formatMm=(v:number)=>v.toLocaleString('en-US',{maximumFractionDigits:1});
|
|
export function dimensionGraphics(entity:Extract<Entity,{kind:'dimension'}>):Entity[]{
|
|
const {a,b,axis,position,height,source,layer}=entity,s=height/CAD_STYLE.dimensionText,arrow=CAD_STYLE.arrow*s;
|
|
const p:Point=axis==='x'?[a[0],position]:[position,a[1]],q:Point=axis==='x'?[b[0],position]:[position,b[1]],u:Point=axis==='x'?[Math.sign(q[0]-p[0])||1,0]:[0,Math.sign(q[1]-p[1])||1];
|
|
const n:Point=[-u[1],u[0]],line=(a:Point,b:Point):Entity=>({kind:'line',a,b,source,layer});
|
|
const ext=(a:Point,b:Point):Entity=>{const d=Math.hypot(b[0]-a[0],b[1]-a[1]),k=d?1/d:0,dx=(b[0]-a[0])*k,dy=(b[1]-a[1])*k;return line([a[0]+dx*Math.min(CAD_STYLE.extensionGap*s,d),a[1]+dy*Math.min(CAD_STYLE.extensionGap*s,d)],[b[0]+dx*s,b[1]+dy*s]);};
|
|
const length=Math.hypot(q[0]-p[0],q[1]-p[1]),textWidth=(entity.label??formatMm(entity.value)).length*height*.6,external=length<textWidth+2*arrow+2*s;
|
|
const out:Entity[]=[ext(a,p),ext(b,q),line(external?[p[0]-u[0]*3*arrow,p[1]-u[1]*3*arrow]:p,external?[q[0]+u[0]*3*arrow,q[1]+u[1]*3*arrow]:q)];
|
|
for(const point of [p,q])out.push({kind:'hatch',points:Array.from({length:16},(_,i)=>[point[0]+arrow*.5*Math.cos(i*Math.PI/8),point[1]+arrow*.5*Math.sin(i*Math.PI/8)] as Point),pattern:'SOLID',spacing:s,angle:0,color:'#ff0000',source,layer});
|
|
out.push({kind:'text',point:[(p[0]+q[0])/2+(axis==='y'?-1.2*s:0),(p[1]+q[1])/2+(axis==='x'?1.2*s:0)],text:entity.label??formatMm(entity.value),height,rotation:axis==='y'?90:0,align:'center',source,layer});
|
|
return out;
|
|
}
|