@tscircuit/core 0.0.884 → 0.0.886

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 +193 -8
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -6756,6 +6756,149 @@ function Trace_doInitialPcbTraceRender(trace) {
6756
6756
 
6757
6757
  // lib/components/primitive-components/Trace/Trace_doInitialPcbManualTraceRender.ts
6758
6758
  import { applyToPoint as applyToPoint7, identity as identity3 } from "transformation-matrix";
6759
+
6760
+ // lib/utils/trace-clipping/computeLineRectIntersection.ts
6761
+ function computeLineRectIntersection(params) {
6762
+ const { lineStart, lineEnd, rectCenter, rectWidth, rectHeight } = params;
6763
+ const left = rectCenter.x - rectWidth / 2;
6764
+ const right = rectCenter.x + rectWidth / 2;
6765
+ const top = rectCenter.y + rectHeight / 2;
6766
+ const bottom = rectCenter.y - rectHeight / 2;
6767
+ const dx = lineEnd.x - lineStart.x;
6768
+ const dy = lineEnd.y - lineStart.y;
6769
+ const intersections = [];
6770
+ if (dx !== 0) {
6771
+ const t = (left - lineStart.x) / dx;
6772
+ if (t >= 0 && t <= 1) {
6773
+ const y = lineStart.y + t * dy;
6774
+ if (y >= bottom && y <= top) {
6775
+ intersections.push({ x: left, y, t });
6776
+ }
6777
+ }
6778
+ }
6779
+ if (dx !== 0) {
6780
+ const t = (right - lineStart.x) / dx;
6781
+ if (t >= 0 && t <= 1) {
6782
+ const y = lineStart.y + t * dy;
6783
+ if (y >= bottom && y <= top) {
6784
+ intersections.push({ x: right, y, t });
6785
+ }
6786
+ }
6787
+ }
6788
+ if (dy !== 0) {
6789
+ const t = (bottom - lineStart.y) / dy;
6790
+ if (t >= 0 && t <= 1) {
6791
+ const x = lineStart.x + t * dx;
6792
+ if (x >= left && x <= right) {
6793
+ intersections.push({ x, y: bottom, t });
6794
+ }
6795
+ }
6796
+ }
6797
+ if (dy !== 0) {
6798
+ const t = (top - lineStart.y) / dy;
6799
+ if (t >= 0 && t <= 1) {
6800
+ const x = lineStart.x + t * dx;
6801
+ if (x >= left && x <= right) {
6802
+ intersections.push({ x, y: top, t });
6803
+ }
6804
+ }
6805
+ }
6806
+ if (intersections.length === 0) return null;
6807
+ intersections.sort((a, b) => a.t - b.t);
6808
+ return { x: intersections[0].x, y: intersections[0].y };
6809
+ }
6810
+
6811
+ // lib/utils/trace-clipping/computeLineCircleIntersection.ts
6812
+ function computeLineCircleIntersection(params) {
6813
+ const { lineStart, lineEnd, circleCenter, circleRadius } = params;
6814
+ const x1 = lineStart.x - circleCenter.x;
6815
+ const y1 = lineStart.y - circleCenter.y;
6816
+ const x2 = lineEnd.x - circleCenter.x;
6817
+ const y2 = lineEnd.y - circleCenter.y;
6818
+ const dx = x2 - x1;
6819
+ const dy = y2 - y1;
6820
+ const a = dx * dx + dy * dy;
6821
+ const b = 2 * (x1 * dx + y1 * dy);
6822
+ const c = x1 * x1 + y1 * y1 - circleRadius * circleRadius;
6823
+ const discriminant = b * b - 4 * a * c;
6824
+ if (discriminant < 0) return null;
6825
+ const sqrtDisc = Math.sqrt(discriminant);
6826
+ const t1 = (-b - sqrtDisc) / (2 * a);
6827
+ const t2 = (-b + sqrtDisc) / (2 * a);
6828
+ let t = null;
6829
+ if (t1 >= 0 && t1 <= 1) {
6830
+ t = t1;
6831
+ } else if (t2 >= 0 && t2 <= 1) {
6832
+ t = t2;
6833
+ }
6834
+ if (t === null) return null;
6835
+ return {
6836
+ x: lineStart.x + t * dx,
6837
+ y: lineStart.y + t * dy
6838
+ };
6839
+ }
6840
+
6841
+ // lib/utils/trace-clipping/clipTraceEndAtPad.ts
6842
+ function clipTraceEndAtPad(params) {
6843
+ const { traceStart, traceEnd, traceWidth, port } = params;
6844
+ const pcbPrimitive = port.matchedComponents.find((c) => c.isPcbPrimitive);
6845
+ if (!pcbPrimitive) {
6846
+ return traceEnd;
6847
+ }
6848
+ const padBounds = pcbPrimitive._getPcbCircuitJsonBounds();
6849
+ const padWidth = padBounds.width;
6850
+ const padHeight = padBounds.height;
6851
+ const padCenter = padBounds.center;
6852
+ const smallestPadDimension = Math.min(padWidth, padHeight);
6853
+ if (traceWidth <= smallestPadDimension / 2) {
6854
+ return traceEnd;
6855
+ }
6856
+ let clippedPoint = null;
6857
+ if (pcbPrimitive.componentName === "SmtPad") {
6858
+ const smtPad = pcbPrimitive;
6859
+ const padShape = smtPad._parsedProps.shape;
6860
+ if (padShape === "circle") {
6861
+ const radius = smtPad._parsedProps.radius;
6862
+ clippedPoint = computeLineCircleIntersection({
6863
+ lineStart: traceStart,
6864
+ lineEnd: traceEnd,
6865
+ circleCenter: padCenter,
6866
+ circleRadius: radius
6867
+ });
6868
+ } else if (padShape === "rect" || padShape === "rotated_rect" || padShape === "pill" || padShape === "polygon") {
6869
+ clippedPoint = computeLineRectIntersection({
6870
+ lineStart: traceStart,
6871
+ lineEnd: traceEnd,
6872
+ rectCenter: padCenter,
6873
+ rectWidth: padWidth,
6874
+ rectHeight: padHeight
6875
+ });
6876
+ }
6877
+ } else if (pcbPrimitive.componentName === "PlatedHole") {
6878
+ const platedHole = pcbPrimitive;
6879
+ const holeShape = platedHole._parsedProps.shape;
6880
+ if (holeShape === "circle") {
6881
+ const outerDiameter = platedHole._parsedProps.outerDiameter;
6882
+ clippedPoint = computeLineCircleIntersection({
6883
+ lineStart: traceStart,
6884
+ lineEnd: traceEnd,
6885
+ circleCenter: padCenter,
6886
+ circleRadius: outerDiameter / 2
6887
+ });
6888
+ } else {
6889
+ clippedPoint = computeLineRectIntersection({
6890
+ lineStart: traceStart,
6891
+ lineEnd: traceEnd,
6892
+ rectCenter: padCenter,
6893
+ rectWidth: padWidth,
6894
+ rectHeight: padHeight
6895
+ });
6896
+ }
6897
+ }
6898
+ return clippedPoint ?? traceEnd;
6899
+ }
6900
+
6901
+ // lib/components/primitive-components/Trace/Trace_doInitialPcbManualTraceRender.ts
6759
6902
  function Trace_doInitialPcbManualTraceRender(trace) {
6760
6903
  if (trace.root?.pcbDisabled) return;
6761
6904
  const { db } = trace.root;
@@ -6796,19 +6939,31 @@ function Trace_doInitialPcbManualTraceRender(trace) {
6796
6939
  const layer2 = sharedLayer ?? startLayers[0] ?? endLayers[0] ?? "top";
6797
6940
  const startPos = startPort._getGlobalPcbPositionAfterLayout();
6798
6941
  const endPos = endPort._getGlobalPcbPositionAfterLayout();
6942
+ const clippedStartPos = clipTraceEndAtPad({
6943
+ traceStart: endPos,
6944
+ traceEnd: startPos,
6945
+ traceWidth: width,
6946
+ port: startPort
6947
+ });
6948
+ const clippedEndPos = clipTraceEndAtPad({
6949
+ traceStart: startPos,
6950
+ traceEnd: endPos,
6951
+ traceWidth: width,
6952
+ port: endPort
6953
+ });
6799
6954
  const route2 = [
6800
6955
  {
6801
6956
  route_type: "wire",
6802
- x: startPos.x,
6803
- y: startPos.y,
6957
+ x: clippedStartPos.x,
6958
+ y: clippedStartPos.y,
6804
6959
  width,
6805
6960
  layer: layer2,
6806
6961
  start_pcb_port_id: startPort.pcb_port_id
6807
6962
  },
6808
6963
  {
6809
6964
  route_type: "wire",
6810
- x: endPos.x,
6811
- y: endPos.y,
6965
+ x: clippedEndPos.x,
6966
+ y: clippedEndPos.y,
6812
6967
  width,
6813
6968
  layer: layer2,
6814
6969
  end_pcb_port_id: endPort.pcb_port_id
@@ -18534,7 +18689,7 @@ var VoltageProbe = class extends PrimitiveComponent2 {
18534
18689
  }
18535
18690
  doInitialSimulationRender() {
18536
18691
  const { db } = this.root;
18537
- const { connectsTo, name } = this._parsedProps;
18692
+ const { connectsTo, name, referenceTo, color } = this._parsedProps;
18538
18693
  const subcircuit = this.getSubcircuit();
18539
18694
  if (!subcircuit) {
18540
18695
  this.renderError("VoltageProbe must be inside a subcircuit");
@@ -18567,7 +18722,35 @@ var VoltageProbe = class extends PrimitiveComponent2 {
18567
18722
  this.renderError(`Could not identify connected source for VoltageProbe`);
18568
18723
  return;
18569
18724
  }
18570
- this.color = getSimulationColorForId(connectedId);
18725
+ let referencePort = null;
18726
+ let referenceNet = null;
18727
+ if (referenceTo) {
18728
+ const referenceTargets = Array.isArray(referenceTo) ? referenceTo : [referenceTo];
18729
+ if (referenceTargets.length !== 1) {
18730
+ this.renderError("VoltageProbe must reference exactly one port or net");
18731
+ return;
18732
+ }
18733
+ const referenceSelector = referenceTargets[0];
18734
+ referencePort = subcircuit.selectOne(referenceSelector, {
18735
+ type: "port"
18736
+ });
18737
+ referenceNet = !referencePort ? subcircuit.selectOne(referenceSelector, {
18738
+ type: "net"
18739
+ }) : null;
18740
+ if (referenceNet && referenceNet.componentName !== "Net") {
18741
+ this.renderError(
18742
+ `VoltageProbe reference target "${referenceSelector}" resolved to a non-net component "${referenceNet.componentName}".`
18743
+ );
18744
+ return;
18745
+ }
18746
+ if (!referencePort && !referenceNet) {
18747
+ this.renderError(
18748
+ `VoltageProbe could not find reference target "${referenceSelector}"`
18749
+ );
18750
+ return;
18751
+ }
18752
+ }
18753
+ this.color = color ?? getSimulationColorForId(connectedId);
18571
18754
  let finalName = name;
18572
18755
  if (!finalName) {
18573
18756
  finalName = targets[0].split(" > ").map((s) => s.replace(/^\./, "")).join(".");
@@ -18577,6 +18760,8 @@ var VoltageProbe = class extends PrimitiveComponent2 {
18577
18760
  name: finalName,
18578
18761
  signal_input_source_port_id: port?.source_port_id ?? void 0,
18579
18762
  signal_input_source_net_id: net?.source_net_id ?? void 0,
18763
+ reference_input_source_port_id: referencePort?.source_port_id ?? void 0,
18764
+ reference_input_source_net_id: referenceNet?.source_net_id ?? void 0,
18580
18765
  subcircuit_id: subcircuit.subcircuit_id || void 0,
18581
18766
  color: this.color
18582
18767
  });
@@ -18635,7 +18820,7 @@ import { identity as identity6 } from "transformation-matrix";
18635
18820
  var package_default = {
18636
18821
  name: "@tscircuit/core",
18637
18822
  type: "module",
18638
- version: "0.0.883",
18823
+ version: "0.0.885",
18639
18824
  types: "dist/index.d.ts",
18640
18825
  main: "dist/index.js",
18641
18826
  module: "dist/index.js",
@@ -18698,7 +18883,7 @@ var package_default = {
18698
18883
  "circuit-json-to-connectivity-map": "^0.0.22",
18699
18884
  "circuit-json-to-gltf": "^0.0.31",
18700
18885
  "circuit-json-to-simple-3d": "^0.0.9",
18701
- "circuit-json-to-spice": "^0.0.25",
18886
+ "circuit-json-to-spice": "^0.0.26",
18702
18887
  "circuit-to-svg": "^0.0.280",
18703
18888
  concurrently: "^9.1.2",
18704
18889
  "connectivity-map": "^1.0.0",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.884",
4
+ "version": "0.0.886",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -64,7 +64,7 @@
64
64
  "circuit-json-to-connectivity-map": "^0.0.22",
65
65
  "circuit-json-to-gltf": "^0.0.31",
66
66
  "circuit-json-to-simple-3d": "^0.0.9",
67
- "circuit-json-to-spice": "^0.0.25",
67
+ "circuit-json-to-spice": "^0.0.26",
68
68
  "circuit-to-svg": "^0.0.280",
69
69
  "concurrently": "^9.1.2",
70
70
  "connectivity-map": "^1.0.0",