@tscircuit/core 0.0.2013 → 0.0.2014

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +105 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3196,6 +3196,53 @@ function fillPolygonWithRects(polygon, options = {}) {
3196
3196
  return rects;
3197
3197
  }
3198
3198
 
3199
+ // lib/utils/obstacles/generateApproximatingRects.ts
3200
+ function generateApproximatingRects(rotatedRect, numRects = 2) {
3201
+ const { center, width, height, rotation: rotation5 } = rotatedRect;
3202
+ const rects = [];
3203
+ const angleRad = rotation5 * Math.PI / 180;
3204
+ const cosAngle = Math.cos(angleRad);
3205
+ const sinAngle = Math.sin(angleRad);
3206
+ const normalizedRotation = (rotation5 % 360 + 360) % 360;
3207
+ const sliceAlongWidth = height <= width ? normalizedRotation >= 45 && normalizedRotation < 135 || normalizedRotation >= 225 && normalizedRotation < 315 : normalizedRotation >= 135 && normalizedRotation < 225 || normalizedRotation >= 315 || normalizedRotation < 45;
3208
+ if (sliceAlongWidth) {
3209
+ const sliceWidth = width / numRects;
3210
+ for (let i = 0; i < numRects; i++) {
3211
+ const x = (i - numRects / 2 + 0.5) * sliceWidth;
3212
+ const rotatedX = -x * cosAngle;
3213
+ const rotatedY = -x * sinAngle;
3214
+ const coverageWidth = sliceWidth * 1.1;
3215
+ const coverageHeight = Math.abs(height * cosAngle) + Math.abs(sliceWidth * sinAngle);
3216
+ rects.push({
3217
+ center: {
3218
+ x: center.x + rotatedX,
3219
+ y: center.y + rotatedY
3220
+ },
3221
+ width: coverageWidth,
3222
+ height: coverageHeight
3223
+ });
3224
+ }
3225
+ } else {
3226
+ const sliceHeight = height / numRects;
3227
+ for (let i = 0; i < numRects; i++) {
3228
+ const y = (i - numRects / 2 + 0.5) * sliceHeight;
3229
+ const rotatedX = -y * sinAngle;
3230
+ const rotatedY = y * cosAngle;
3231
+ const coverageWidth = Math.abs(width * cosAngle) + Math.abs(sliceHeight * sinAngle);
3232
+ const coverageHeight = sliceHeight * 1.1;
3233
+ rects.push({
3234
+ center: {
3235
+ x: center.x + rotatedX,
3236
+ y: center.y + rotatedY
3237
+ },
3238
+ width: coverageWidth,
3239
+ height: coverageHeight
3240
+ });
3241
+ }
3242
+ }
3243
+ return rects;
3244
+ }
3245
+
3199
3246
  // lib/utils/obstacles/getAxisAlignedRectFromPolygon.ts
3200
3247
  var AXIS_ALIGNED_RECT_TOLERANCE_MM = 1e-3;
3201
3248
  var getAxisAlignedRectFromPolygon = (points) => {
@@ -3233,6 +3280,59 @@ var getAxisAlignedRectFromPolygon = (points) => {
3233
3280
  };
3234
3281
  };
3235
3282
 
3283
+ // lib/utils/obstacles/getObstaclesFromPcbKeepoutOutline.ts
3284
+ var getObstaclesFromPcbKeepoutOutline = (keepout, componentId) => {
3285
+ const { outline, stroke_width } = keepout;
3286
+ if (!Number.isFinite(stroke_width) || stroke_width <= 0) return [];
3287
+ const obstacles = [];
3288
+ for (let segmentIndex = 0; segmentIndex < outline.length - 1; segmentIndex++) {
3289
+ const start = outline[segmentIndex];
3290
+ const end = outline[segmentIndex + 1];
3291
+ const deltaX = end.x - start.x;
3292
+ const deltaY = end.y - start.y;
3293
+ const segmentLength = Math.hypot(deltaX, deltaY);
3294
+ if (!Number.isFinite(segmentLength) || segmentLength === 0) continue;
3295
+ const approximatingRects = generateApproximatingRects({
3296
+ center: {
3297
+ x: (start.x + end.x) / 2,
3298
+ y: (start.y + end.y) / 2
3299
+ },
3300
+ width: segmentLength,
3301
+ height: stroke_width,
3302
+ rotation: Math.atan2(deltaY, deltaX) * 180 / Math.PI
3303
+ });
3304
+ for (const [approximationIndex, rect] of approximatingRects.entries()) {
3305
+ obstacles.push({
3306
+ obstacleId: `${keepout.pcb_keepout_id}_segment_${segmentIndex}_rect_${approximationIndex}`,
3307
+ componentId,
3308
+ type: "rect",
3309
+ layers: keepout.layers,
3310
+ ...rect,
3311
+ connectedTo: []
3312
+ });
3313
+ }
3314
+ }
3315
+ const isClosed = outline.length > 1 && outline[0].x === outline.at(-1)?.x && outline[0].y === outline.at(-1)?.y;
3316
+ const joinPoints = isClosed ? outline.slice(0, -1) : outline;
3317
+ for (const [joinIndex, point6] of joinPoints.entries()) {
3318
+ const approximatingRects = fillCircleWithRects(
3319
+ { center: point6, radius: stroke_width / 2 },
3320
+ { rectHeight: stroke_width / 4 }
3321
+ );
3322
+ for (const [approximationIndex, rect] of approximatingRects.entries()) {
3323
+ obstacles.push({
3324
+ obstacleId: `${keepout.pcb_keepout_id}_join_${joinIndex}_rect_${approximationIndex}`,
3325
+ componentId,
3326
+ type: "rect",
3327
+ layers: keepout.layers,
3328
+ ...rect,
3329
+ connectedTo: []
3330
+ });
3331
+ }
3332
+ }
3333
+ return obstacles;
3334
+ };
3335
+
3236
3336
  // lib/utils/obstacles/getObstaclesFromRoute.ts
3237
3337
  var isCloseTo = (a, b) => Math.abs(a - b) < 1e-4;
3238
3338
  var getObstaclesFromRoute = (route, source_trace_id, { viaDiameter = 0.5 } = {}) => {
@@ -3472,6 +3572,10 @@ var getObstaclesFromCircuitJson = (circuitJson, connMap) => {
3472
3572
  height: element.height,
3473
3573
  connectedTo: []
3474
3574
  });
3575
+ } else if (element.shape === "outline") {
3576
+ obstacles.push(
3577
+ ...getObstaclesFromPcbKeepoutOutline(element, pcbComponentId)
3578
+ );
3475
3579
  }
3476
3580
  } else if (element.type === "pcb_cutout") {
3477
3581
  if (element.shape === "rect") {
@@ -64471,7 +64575,7 @@ function Group_getRoutingPhasePlans(group) {
64471
64575
  var package_default = {
64472
64576
  name: "@tscircuit/core",
64473
64577
  type: "module",
64474
- version: "0.0.2012",
64578
+ version: "0.0.2013",
64475
64579
  types: "dist/index.d.ts",
64476
64580
  main: "dist/index.js",
64477
64581
  module: "dist/index.js",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.2013",
4
+ "version": "0.0.2014",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",