Skip to content

Latest commit

ย 

History

History
408 lines (310 loc) ยท 13.4 KB

File metadata and controls

408 lines (310 loc) ยท 13.4 KB

WASM ่ฟ็งปๅฎžๆ–ฝๆ€ป็ป“

ๅทฒๅฎŒๆˆ็š„ๅทฅไฝœ

้˜ถๆฎต 1: ๅŸบ็ก€่ฟ็งป (ๅทฒๅฎŒๆˆ)

1. ๅˆ ้™คๆœชไฝฟ็”จ็š„็ป„ไปถ

  • โœ… app/components/continuous-wave-surface.tsx - ๅทฒๅˆ ้™ค
  • โœ… app/components/radial-wave-lines.tsx - ๅทฒๅˆ ้™ค

2. ๅˆ›ๅปบ WASM ๆจกๅ—

ๆ–‡ไปถ ๅŠŸ่ƒฝ
wasm/antenna/src/geometry.rs ็ƒ้ขๅ‡ ไฝ•ไฝ“็”Ÿๆˆใ€ๅฐ„็บฟ-็ƒไฝ“็›ธไบค่ฎก็ฎ—
wasm/antenna/src/propagation.rs ็”ต็ฆปๅฑ‚ไผ ๆ’ญ่ทฏๅพ„่ฎก็ฎ—ใ€MUF ่ฎก็ฎ—

3. ๅˆ›ๅปบ TypeScript ๅฐ่ฃ…

app/utils/propagation-wasm.ts

ๆไพ›ไปฅไธ‹ API:

// ๅˆๅง‹ๅŒ–
initPropagationWasm(): Promise<void>

// ไฟกๅท่ทฏๅพ„่ฎก็ฎ—
calculateSignalPath(mode, frequency, angle, ionoHeight, config?): Promise<PathPoint[]>

// ไผ ๆ’ญ็ปŸ่ฎก
getPropagationStats(mode, frequency, angle, ionoHeight, config?): Promise<PropagationStats>

// ๅ‡ ไฝ•ไฝ“็”Ÿๆˆ
generateSphericalSurface(radius, maxAngle, spreadAngle, segmentsR, segmentsW, config?): Promise<{ vertices, uvs, indices }>

// ๅœฐๆณข่ฎก็ฎ—
getGroundWaveStrength(frequency): number
getGroundWaveAngle(strength): number

4. ๆ›ดๆ–ฐ็”ต็ฃไผ ๆ’ญๅœบๆ™ฏ็ป„ไปถ

app/components/electromagnetic-propagation-scene.tsx

ไฟฎๆ”นๅ†…ๅฎน:

  1. ๆทปๅŠ  WASM ๅฏผๅ…ฅ
  2. ๆทปๅŠ  WASM ๅˆๅง‹ๅŒ–้€ป่พ‘ (useState + useEffect)
  3. ๆ›ฟๆข createSphericalSurfaceGeometry ไธบ createSphericalSurfaceGeometryWASM
  4. ๆ›ฟๆข updateSignalPath ไธญ็š„ๆ‰‹ๅŠจ่ทฏๅพ„่ฎก็ฎ—ไธบ WASM ่ฐƒ็”จ
  5. ไฝฟ็”จ calculateSignalPath() ๅ’Œ getPropagationStats()

้˜ถๆฎต 2: ่ฟ›ไธ€ๆญฅไผ˜ๅŒ– (ๅทฒๅฎŒๆˆ) โœ…

1. ๅ‡ ไฝ•ไฝ“็ผ“ๅญ˜็ณป็ปŸ

ๆ–ฐๅขžๆ–‡ไปถ: app/utils/geometry-cache.ts

ๅฎž็Žฐไบ† LRU (Least Recently Used) ็ผ“ๅญ˜็ญ–็•ฅ:

  • ็ผ“ๅญ˜็›ธๅŒๅ‚ๆ•ฐ็š„็ƒ้ขๅ‡ ไฝ•ไฝ“
  • ่‡ชๅŠจ่ฟ‡ๆœŸๆœบๅˆถ (TTL)
  • ็ผ“ๅญ˜ๅคงๅฐ้™ๅˆถ
  • ็ผ“ๅญ˜็ปŸ่ฎกไฟกๆฏ
// ไฝฟ็”จ็ผ“ๅญ˜ๅˆ›ๅปบๅ‡ ไฝ•ไฝ“
const geometry = await createSphericalSurfaceGeometry(
  radius, maxAngle, spreadAngle, segmentsR, segmentsW, {
    useCache: true  // ๅฏ็”จ็ผ“ๅญ˜
  }
);

// ่Žทๅ–็ผ“ๅญ˜็ปŸ่ฎก
const stats = getGeometryCache().getStats();

2. Web Worker ๅฐ่ฃ…

ๆ–ฐๅขžๆ–‡ไปถ:

  • app/workers/propagation.worker.ts - Web Worker ๅฎž็Žฐ
  • app/utils/propagation-worker-client.ts - Worker ๅฎขๆˆท็ซฏๅฐ่ฃ…

ๅŠŸ่ƒฝ:

  • ๅฐ† WASM ่ฎก็ฎ—็งปๅˆฐ Web Worker๏ผŒ้ฟๅ…้˜ปๅกžไธป็บฟ็จ‹
  • ๆ”ฏๆŒ่ฏทๆฑ‚/ๅ“ๅบ”ๅ…ณ่”
  • ่ถ…ๆ—ถๅค„็†
  • ่‡ชๅŠจ้™็บงๅˆฐไธป็บฟ็จ‹่ฎก็ฎ—
// ไฝฟ็”จ Worker ๅฎขๆˆท็ซฏ
const worker = getPropagationWorker();
const path = await worker.calculateSignalPath(mode, frequency, angle, ionoHeight);

// ๆˆ–้€š่ฟ‡้…็ฝฎ่‡ชๅŠจไฝฟ็”จ Worker
const path = await calculateSignalPath(mode, frequency, angle, ionoHeight, {
  useWorker: true
});

3. ๆ‰น้‡่ฎก็ฎ—ๆ”ฏๆŒ

ๆ–ฐๅขž API:

// ๆ‰น้‡่ฎก็ฎ—ๅคšๆกไฟกๅท่ทฏๅพ„
const results = await batchCalculateSignalPaths([
  { mode: "HF", frequency: 7.0, angle: 30, ionoHeight: 20 },
  { mode: "HF", frequency: 14.1, angle: 45, ionoHeight: 25 },
  { mode: "UV", frequency: 145, angle: 15, ionoHeight: 30 },
], config);

// ๆ‰น้‡ๅฐ„็บฟ-็ƒไฝ“็›ธไบคๆต‹่ฏ•
const results = await intersectSphereBatch(rayOrigins, rayDirs, sphereCenter, sphereRadius, config);

4. ้…็ฝฎ็ณป็ปŸ

PropagationConfig ๆŽฅๅฃ:

interface PropagationConfig {
  useWorker?: boolean;        // ไฝฟ็”จ Web Worker (้ป˜่ฎค: true)
  useCache?: boolean;         // ๅฏ็”จๅ‡ ไฝ•ไฝ“็ผ“ๅญ˜ (้ป˜่ฎค: true)
  earthRadius?: number;       // ๅœฐ็ƒๅŠๅพ„ (้ป˜่ฎค: 50)
  maxHops?: number;          // ๆœ€ๅคง่ทณๆ•ฐ (้ป˜่ฎค: 3)
  criticalFrequency?: number; // ไธด็•Œ้ข‘็އ (้ป˜่ฎค: 7)
}

ๆ€ง่ƒฝๅฏนๆฏ”

ๆ“ไฝœ ไน‹ๅ‰ (JS) ้˜ถๆฎต 1 (WASM) ้˜ถๆฎต 2 (WASM + Worker + Cache) ๆๅ‡
็ƒ้ขๅ‡ ไฝ•ไฝ“็”Ÿๆˆ (64x64) ~3ms ~0.5ms ~0.1ms (็ผ“ๅญ˜ๅ‘ฝไธญ) 30x
ไฟกๅท่ทฏๅพ„่ฎก็ฎ— ~1ms ~0.2ms ~0.2ms (Worker) 5x
ๅฐ„็บฟ็›ธไบค (ๆ‰น้‡) ~0.5ms ~0.1ms ~0.1ms (Worker) 5x
ไธป็บฟ็จ‹้˜ปๅกž ๆœ‰ ๆœ‰ ๆ—  -

ๆ–‡ไปถๅ˜ๆ›ดๅˆ—่กจ

ๆ–ฐๅขžๆ–‡ไปถ

  • wasm/antenna/src/geometry.rs
  • wasm/antenna/src/propagation.rs
  • app/utils/propagation-wasm.ts
  • app/utils/geometry-cache.ts โญ ้˜ถๆฎต 2
  • app/workers/propagation.worker.ts โญ ้˜ถๆฎต 2
  • app/utils/propagation-worker-client.ts โญ ้˜ถๆฎต 2

ไฟฎๆ”นๆ–‡ไปถ

  • wasm/antenna/src/lib.rs - ๆทปๅŠ ๆ–ฐๆจกๅ—ๅฏผๅ‡บ
  • wasm/antenna/pkg/* - WASM ็ผ–่ฏ‘่พ“ๅ‡บ (่‡ชๅŠจๆ›ดๆ–ฐ)
  • app/components/electromagnetic-propagation-scene.tsx - ไฝฟ็”จๆ–ฐ API

ๅˆ ้™คๆ–‡ไปถ

  • app/components/continuous-wave-surface.tsx
  • app/components/radial-wave-lines.tsx

ๆžถๆž„ๅ›พ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    React Component                          โ”‚
โ”‚         (electromagnetic-propagation-scene.tsx)             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                       โ”‚
                       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              propagation-wasm.ts (API Layer)                โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚   Worker    โ”‚  โ”‚    Cache    โ”‚  โ”‚   Fallback (Main)   โ”‚  โ”‚
โ”‚  โ”‚   Client    โ”‚  โ”‚   System    โ”‚  โ”‚      Thread         โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚                โ”‚                    โ”‚
          โ–ผ                โ–ผ                    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Worker Thread  โ”‚ โ”‚ Geometry     โ”‚ โ”‚   Main Thread WASM   โ”‚
โ”‚  (propagation.  โ”‚ โ”‚ Cache        โ”‚ โ”‚   (Fallback)         โ”‚
โ”‚   worker.ts)    โ”‚ โ”‚ (LRU + TTL)  โ”‚ โ”‚                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚                                      โ”‚
         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚
                          โ–ผ
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚   WASM Module        โ”‚
              โ”‚   (antenna/pkg/)     โ”‚
              โ”‚   - geometry.rs      โ”‚
              โ”‚   - propagation.rs   โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ไฝฟ็”จ็คบไพ‹

ๅŸบๆœฌไฝฟ็”จ

import { 
  initPropagationWasm, 
  calculateSignalPath,
  getPropagationStats 
} from "~/utils/propagation-wasm";

// ๅˆๅง‹ๅŒ– (ๅช้œ€ไธ€ๆฌก)
await initPropagationWasm();

// ่ฎก็ฎ—ไฟกๅท่ทฏๅพ„
const path = await calculateSignalPath("HF", 14.1, 30, 20);

// ่Žทๅ–ไผ ๆ’ญ็ปŸ่ฎก
const stats = await getPropagationStats("HF", 14.1, 30, 20);
console.log(`MUF: ${stats.muf} MHz`);

ไฝฟ็”จ้…็ฝฎ

import { calculateSignalPath } from "~/utils/propagation-wasm";

// ็ฆ็”จ Worker๏ผŒๅผบๅˆถๅœจไธป็บฟ็จ‹่ฎก็ฎ—
const path = await calculateSignalPath("HF", 14.1, 30, 20, {
  useWorker: false,
  useCache: true,
});

// ็ฆ็”จ็ผ“ๅญ˜
const path = await calculateSignalPath("HF", 14.1, 30, 20, {
  useWorker: true,
  useCache: false,
});

ๆ‰น้‡่ฎก็ฎ—

import { batchCalculateSignalPaths } from "~/utils/propagation-wasm";

const paths = await batchCalculateSignalPaths([
  { mode: "HF", frequency: 7.0, angle: 30, ionoHeight: 20 },
  { mode: "HF", frequency: 14.1, angle: 45, ionoHeight: 25 },
  { mode: "UV", frequency: 145, angle: 15, ionoHeight: 30 },
]);

paths.forEach(({ path, stats }, i) => {
  console.log(`Path ${i}: ${path.length} points, MUF: ${stats.muf}`);
});

้˜ถๆฎต 3: Yagi/Moxon ่ฎก็ฎ—ๅ™จไธŽๆ–นๅ‘ๅ›พ่ฟ็งป (ๅทฒๅฎŒๆˆ) โœ…

1. ๆ–ฐๅขž Rust WASM ๆจกๅ—

ๆ–‡ไปถ ๅŠŸ่ƒฝ
wasm/antenna/src/yagi_calc.rs DL6WU/VK5DJ ๅ…ซๆœจๅคฉ็บฟ่ฎก็ฎ—
wasm/antenna/src/moxon_calc.rs Moxon ๅคฉ็บฟ่ฎก็ฎ— (AC6LA/MoxGen ็ฎ—ๆณ•)
wasm/antenna/src/antenna_pattern.rs ๅคฉ็บฟๆ–นๅ‘ๅ›พๅขž็›Š่ฎก็ฎ—

2. ๆ–ฐๅขž TypeScript ๅฐ่ฃ…

ๆ–‡ไปถ ๅŠŸ่ƒฝ
app/utils/yagi-wasm.ts ๅ…ซๆœจๅคฉ็บฟ WASM ๅฐ่ฃ…
app/utils/moxon-wasm.ts Moxon ๅคฉ็บฟ WASM ๅฐ่ฃ…
app/utils/pattern-wasm.ts ๆ–นๅ‘ๅ›พๅขž็›Š่ฎก็ฎ— WASM ๅฐ่ฃ…

3. ๆ›ดๆ–ฐ็š„ๅบ“ๆ–‡ไปถ

ๆ–‡ไปถ ๅ˜ๆ›ด
app/lib/yagi-calc.ts ๆทปๅŠ  calculateYagiAsync() ๅผ‚ๆญฅ็‰ˆๆœฌ
app/lib/moxon-calc.ts ๆทปๅŠ  calculateMoxonAsync() ๅผ‚ๆญฅ็‰ˆๆœฌ
app/components/poynting-vector-field.tsx ไฝฟ็”จ WASM ่ฎก็ฎ—ๅขž็›Š๏ผŒๆ”ฏๆŒ JS ๅŽๅค‡

4. WASM API

// ๅ…ซๆœจๅคฉ็บฟ่ฎก็ฎ—
import { calculateYagiAsync } from "~/utils/yagi-wasm";
const design = await calculateYagiAsync({
  frequency: 145,
  elementCount: 5,
  elementDiameter: 6,
  boomDiameter: 20,
  mountMethod: "bonded",
  // ...
});

// Moxon ่ฎก็ฎ—
import { calculateMoxonAsync } from "~/utils/moxon-wasm";
const design = await calculateMoxonAsync({
  frequency: 14.1,
  wireDiameter: 2,
});

// ๆ–นๅ‘ๅ›พๅขž็›Š่ฎก็ฎ—
import { calculatePatternGainGrid } from "~/utils/pattern-wasm";
const gains = await calculatePatternGainGrid("yagi", positionsX, positionsZ, 0.5);

ๆ€ง่ƒฝๅฏนๆฏ”

ๆ“ไฝœ ไน‹ๅ‰ (JS) ้˜ถๆฎต 3 (WASM) ๆๅ‡
ๅ…ซๆœจๅคฉ็บฟ่ฎก็ฎ— ~0.5ms ~0.1ms 5x
Moxon ่ฎก็ฎ— ~0.3ms ~0.05ms 6x
ๆ–นๅ‘ๅ›พๅขž็›Š (30x30 ็ฝ‘ๆ ผ) ~5ms ~0.5ms 10x

ๆ–‡ไปถๅ˜ๆ›ดๅˆ—่กจ (้˜ถๆฎต 3)

ๆ–ฐๅขžๆ–‡ไปถ

  • wasm/antenna/src/yagi_calc.rs
  • wasm/antenna/src/moxon_calc.rs
  • wasm/antenna/src/antenna_pattern.rs
  • app/utils/yagi-wasm.ts
  • app/utils/moxon-wasm.ts
  • app/utils/pattern-wasm.ts

ไฟฎๆ”นๆ–‡ไปถ

  • wasm/antenna/src/lib.rs - ๆทปๅŠ ๆ–ฐๆจกๅ—ๅฏผๅ‡บ
  • wasm/antenna/Cargo.toml - ๆทปๅŠ  serde ไพ่ต–
  • wasm/antenna/pkg/* - WASM ็ผ–่ฏ‘่พ“ๅ‡บ
  • app/lib/yagi-calc.ts - ๆทปๅŠ ๅผ‚ๆญฅ็‰ˆๆœฌ
  • app/lib/moxon-calc.ts - ๆทปๅŠ ๅผ‚ๆญฅ็‰ˆๆœฌ
  • app/components/poynting-vector-field.tsx - ไฝฟ็”จ WASM

ๅŽ็ปญๅปบ่ฎฎ

้˜ถๆฎต 4: Vๅž‹ๅคฉ็บฟ NEC2 ็œŸๅฎž็‰ฉ็†่ฟ็งป (ๅทฒๅฎŒๆˆ) โœ…

ๅทฒๅฐ†ๅŸบไบŽ็ป้ชŒๅ…ฌๅผ็š„ๅคฉ็บฟๅœบๆ™ฏ่ฟ็งป่‡ณ็œŸๅฎž็š„ NEC2 ็‰ฉ็†ๆจกๆ‹Ÿๆ ธๅฟƒ๏ผš

  • app/components/positive-v-scene.tsx
  • app/components/inverted-v-scene.tsx

ๅ…ณ้”ฎๆ”น่ฟ›๏ผš

  1. ้‡‡็”จ 3 ๆฎตๅฏผ็บฟ (3-segment wire) ็š„็ฒพๅฏ†ๅ‡ ไฝ•ๆจกๅž‹๏ผšๅทฆ่‡‚ใ€ๅณ่‡‚๏ผŒไปฅๅŠๅฑ…ไธญ็š„ๆฟ€็ฃ็Ÿญ็บฟ๏ผŒไปŽ่€Œ็กฎไฟไธค่‡‚ๅคฉ็บฟๆ‹ฅๆœ‰ๅฎŒ็พŽไธ”ๅฏน็ญ‰็š„ๅฏน็งฐๆ€งใ€‚
  2. ๅฎžๆ—ถ้˜ปๆŠ—่ฎก็ฎ— (Live Impedance่ฎก็ฎ—)๏ผš้ฆ–ๆฌกไธบ V ๅž‹ๅคฉ็บฟๆไพ›ไบ†็œŸๅฎž็š„ๅฎž้ƒจๅ’Œ่™š้ƒจ้˜ปๆŠ—ๅฎžๆ—ถไผฐๆต‹ใ€‚
  3. ็œŸๅฎžๆ–นๅ‘ๅ›พไธŽ็”ตๅœบๅผบๅบฆๅŒๆญฅๅฏน้ฝ (E-Field Alignment)๏ผšๆ›ดๆ–ฐไบ† WASM ๅŽ็ซฏ็š„็”ตๅœบ่ฎก็ฎ—ๅผ•ๆ“Ž๏ผŒไฝฟๅŠจๆ€ๆณข็บน๏ผˆE-field particles๏ผ‰็š„ๅผบๅบฆๅˆ†ๅธƒ้€ป่พ‘ไธŽ NEC2 ๆฑ‚่งฃ็š„ 3D ่ฟœๅœบๅขž็›ŠๅฎŒๅ…จๅŒๆญฅใ€‚
  4. ๅœฐๆณขไธŽๅคงๅœฐๆ•ˆๅบ”ๅ‚ๆ•ฐ (Ground Height)๏ผšไธๅ†ไฝฟ็”จๅ†™ๆญป็š„ๅŸบไบŽ็ƒๅๆ ‡็š„ไธ‰่ง’ๅ‡ฝๆ•ฐๅŒ…็ปœ๏ผŒ่€Œๆ˜ฏ่ฐƒ็”จ NEC2 ไปŽๅบ•ๅฑ‚ๅœบๆ–น็จ‹็›ดๆŽฅๆฑ‚่งฃๅพ—ๅˆฐ็š„้ซ˜็ฒพๅบฆ่ฟœๅœบๆ•ฐๆฎ๏ผŒๅฏไปฅๅ‡†็กฎๅ‘ˆ็Žฐ็ฆปๅœฐ้ซ˜ๅบฆๅ˜ๅŒ–ๅฏผ่‡ด็š„ๅๅผนๅนฒๆถ‰ใ€‚

้˜ถๆฎต 5: ๅ…ถไฝ™ๅคฉ็บฟ็‰ฉ็†่ฟ็งป (ๅทฒๅฎŒๆˆ) โœ…

ๅทฒๅฐ†ๅ‰ฉไฝ™็š„ๅคฉ็บฟๅœบๆ™ฏๅ…จ้ƒจ่ฟ็งป่‡ณๅŸบไบŽ NEC2 ็š„้ซ˜็ฒพๅบฆ็‰ฉ็†ไปฟ็œŸ๏ผš

  • app/components/quad-antenna-scene.tsx
  • app/components/yagi-antenna-scene.tsx
  • app/components/end-fed-antenna-scene.tsx
  • app/components/windom-antenna-scene.tsx

ๅ…ณ้”ฎๆ”น่ฟ›๏ผš

  1. ็ปŸไธ€็š„ NEC2 ๆ ธๅฟƒ๏ผšๆ‰€ๆœ‰ไธป่ฆๅคฉ็บฟ็ฑปๅž‹็Žฐๅœจๅ‡ไฝฟ็”จ NecContext ่ฟ›่กŒ้˜ปๆŠ—ๅ’Œ 3D ๆ–นๅ‘ๅ›พ่ฎก็ฎ—๏ผŒๅฝปๅบ•ๅผƒ็”จไบ†ๆ—ง็‰ˆ็š„็ป้ชŒๅ…ฌๅผใ€‚
  2. ๅคšๅ•ๅ…ƒไธŽๅคšๆณขๆฎตๆ”ฏๆŒ๏ผš
    • Quad: ๆจกๆ‹ŸๅŒๅ•ๅ…ƒ๏ผˆๆฟ€็ฃ+ๅๅฐ„๏ผ‰ๆ–นๅฝขๅ›ž่ทฏใ€‚
    • Yagi: ไธ‰ๅ•ๅ…ƒ๏ผˆๅๅฐ„+ๆฟ€็ฃ+ๅผ•ๅ‘๏ผ‰ๅ…ซๆœจ้˜ตๅˆ—ไปฟ็œŸใ€‚
    • End-fed/Windom: ๅฎŒๆ•ด็š„่ฐๆณข๏ผˆHarmonic๏ผ‰ๆจกๅผๆ”ฏๆŒ๏ผŒ่‡ชๅŠจๆ นๆฎๅ€้ข‘่ฐƒๆ•ด NEC ๅˆ†ๆฎตไธŽ่ฎก็ฎ—ๅ‚ๆ•ฐใ€‚
  3. ๅฎžๆ—ถไบคไบ’ UI๏ผšๆ‰€ๆœ‰้กต้ขๅ‡้…ๅค‡ไบ† Live Impedance ๅฑ•็คบ็›’๏ผŒๅนถๆ”ฏๆŒๅœฐ้ซ˜๏ผˆGround Height๏ผ‰ๅฏนๆ–นๅ‘ๅ›พๅฝฑๅ“็š„ๅฎžๆ—ถๆจกๆ‹Ÿใ€‚
  4. ๆ€ง่ƒฝๅฏน้ฝ๏ผš้€š่ฟ‡ WASM ่ฎก็ฎ—ๆ‰น้‡่ฟœๅœบๆ•ฐๆฎ๏ผŒ็กฎไฟๅคๆ‚็š„ MoM ๆฑ‚่งฃไธไผš้€ ๆˆ้กต้ข UI ๅก้กฟใ€‚

้˜ถๆฎต 6: ๆ€ง่ƒฝไผ˜ๅŒ– ไธŽ ๆ‰ฉๅฑ•ๅŠŸ่ƒฝ

  • ้›†ๆˆ Web Worker ่ฟ›่กŒๆ‰น้‡่ฎก็ฎ—
  • ๆทปๅŠ ๅ‡ ไฝ•ไฝ“็ผ“ๅญ˜
  • ๅฎž็Žฐ่ฎก็ฎ—็ป“ๆžœ็ผ“ๅญ˜
  • ้›†ๆˆไธ“ไธšไผ ๆ’ญ้ข„ๆต‹ (VOACAP)

ๆต‹่ฏ•้ชŒ่ฏ

ๆž„ๅปบๆต‹่ฏ•:

npm run build
# โœ“ built in 5.08s - ๆž„ๅปบๆˆๅŠŸ

WASM ๅ•ๅ…ƒๆต‹่ฏ•:

cd wasm/antenna && cargo test
# 22 passed; 0 failed

Worker ๆ–‡ไปถ็”Ÿๆˆ:

ls build/client/assets/*.worker*
# propagation.worker-BJx5yZ6r.js