# Nakafa Framework: LLM

URL: /id/subject/high-school/11/mathematics/circle/external-tangent-line-and-internal-tangent-line
Source: https://raw.githubusercontent.com/nakafaai/nakafa.com/refs/heads/main/packages/contents/subject/high-school/11/mathematics/circle/external-tangent-line-and-internal-tangent-line/id.mdx

Output docs content for large language models.

---

import { getColor } from "@repo/design-system/lib/color";
import { LineEquation } from "@repo/design-system/components/contents/line-equation";

export const metadata = {
  title: "Garis Singgung Persekutuan Luar dan Dalam",
  description: "Kuasai garis singgung persekutuan luar dan dalam antar lingkaran. Pelajari rumus, perhitungan, dan selesaikan soal kompleks dengan contoh lengkap.",
  authors: [{ name: "Nabil Akbarazzima Fatih" }],
  date: "05/18/2025",
  subject: "Lingkaran",
};

## Pengertian Garis Singgung Persekutuan

Garis singgung persekutuan adalah garis yang menyinggung dua lingkaran sekaligus. Terdapat dua jenis garis singgung persekutuan:

1. **Garis Singgung Persekutuan Luar**: Garis yang menyinggung kedua lingkaran dari sisi yang sama
2. **Garis Singgung Persekutuan Dalam**: Garis yang menyinggung kedua lingkaran dari sisi yang berlawanan

## Konsep Garis Singgung Persekutuan Luar

Garis singgung persekutuan luar adalah garis yang menyinggung kedua lingkaran dan tidak memotong garis yang menghubungkan kedua pusat lingkaran.

<LineEquation
  title="Garis Singgung Persekutuan Luar"
  description="Dua garis singgung persekutuan luar pada dua lingkaran."
  data={[
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: -4 + 2 * Math.cos(angle),
          y: 2 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: 4 + 3 * Math.cos(angle),
          y: 3 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: [
        { x: -4, y: 0, z: 0 },
        { x: 4, y: 0, z: 0 },
      ],
      color: getColor("ORANGE"),
      showPoints: true,
      labels: [
        { text: "A", at: 0, offset: [-0.5, -0.5, 0] },
        { text: "B", at: 1, offset: [0.5, -0.5, 0] },
      ],
    },
        {
      points: (() => {
        const O1 = { x: -4, y: 0 };
        const O2 = { x: 4, y: 0 };
        const r1 = 2;
        const r2 = 3;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        // Calculate the angle for external tangent
        const sin_alpha = (r2 - r1) / d;
        const cos_alpha = Math.sqrt(1 - sin_alpha * sin_alpha);

        // Direction from O1 to O2
        const dx = O2.x - O1.x;
        const dy = O2.y - O1.y;

        // Normalize direction
        const ux = dx / d;
        const uy = dy / d;

        // Perpendicular direction (rotated 90 degrees)
        const vx = -uy;
        const vy = ux;

        // First tangent line (upper)
        // Tangent point on first circle
        const T1x = O1.x + r1 * (sin_alpha * ux + cos_alpha * vx);
        const T1y = O1.y + r1 * (sin_alpha * uy + cos_alpha * vy);

        // Tangent point on second circle
        const T2x = O2.x + r2 * (sin_alpha * ux + cos_alpha * vx);
        const T2y = O2.y + r2 * (sin_alpha * uy + cos_alpha * vy);

        // Extend the line
        const tdx = T2x - T1x;
        const tdy = T2y - T1y;
        const tlen = Math.sqrt(tdx * tdx + tdy * tdy);
        const tux = tdx / tlen;
        const tuy = tdy / tlen;

        return [
          { x: T1x - 4 * tux, y: T1y - 4 * tuy, z: 0 },
          { x: T2x + 4 * tux, y: T2y + 4 * tuy, z: 0 },
        ];
      })(),
      color: getColor("CYAN"),
      showPoints: false,
      labels: [{ text: "g₁", at: 1, offset: [0, 0.5, 0] }],
    },
    {
      points: (() => {
        const O1 = { x: -4, y: 0 };
        const O2 = { x: 4, y: 0 };
        const r1 = 2;
        const r2 = 3;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        // Calculate the angle for external tangent
        const sin_alpha = (r2 - r1) / d;
        const cos_alpha = Math.sqrt(1 - sin_alpha * sin_alpha);

        // Direction from O1 to O2
        const dx = O2.x - O1.x;
        const dy = O2.y - O1.y;

        // Normalize direction
        const ux = dx / d;
        const uy = dy / d;

        // Perpendicular direction (rotated 90 degrees)
        const vx = -uy;
        const vy = ux;

        // Second tangent line (lower)
        // Tangent point on first circle
        const T1x = O1.x + r1 * (sin_alpha * ux - cos_alpha * vx);
        const T1y = O1.y + r1 * (sin_alpha * uy - cos_alpha * vy);

        // Tangent point on second circle
        const T2x = O2.x + r2 * (sin_alpha * ux - cos_alpha * vx);
        const T2y = O2.y + r2 * (sin_alpha * uy - cos_alpha * vy);

        // Extend the line
        const tdx = T2x - T1x;
        const tdy = T2y - T1y;
        const tlen = Math.sqrt(tdx * tdx + tdy * tdy);
        const tux = tdx / tlen;
        const tuy = tdy / tlen;

        return [
          { x: T1x - 4 * tux, y: T1y - 4 * tuy, z: 0 },
          { x: T2x + 4 * tux, y: T2y + 4 * tuy, z: 0 },
        ];
      })(),
      color: getColor("TEAL"),
      showPoints: false,
      labels: [{ text: "g₂", at: 1, offset: [0, -0.5, 0] }],
    },

]}
cameraPosition={[0, 0, 15]}
showZAxis={false}
/>

### Rumus Panjang Garis Singgung Persekutuan Luar

Untuk dua lingkaran dengan:

- Pusat lingkaran pertama: <InlineMath math="O_1" />
- Pusat lingkaran kedua: <InlineMath math="O_2" />
- Jari-jari lingkaran pertama: <InlineMath math="r_1" />
- Jari-jari lingkaran kedua: <InlineMath math="r_2" />
- Jarak antara pusat: <InlineMath math="d" />

Panjang garis singgung persekutuan luar:

<BlockMath math="l = \sqrt{d^2 - (r_2 - r_1)^2}" />

### Mencari Panjang Garis Singgung Persekutuan Luar

Dua lingkaran masing-masing berpusat di <InlineMath math="A(-3, 0)" /> dengan jari-jari 1.5 dan <InlineMath math="B(3, 0)" /> dengan jari-jari 2.5. Tentukan panjang garis singgung persekutuan luar!

<LineEquation
  title={
    <>
      Lingkaran dengan <InlineMath math="r_1 = 1.5" /> dan{" "}
      <InlineMath math="r_2 = 2.5" />
    </>
  }
  description="Visualisasi garis singgung persekutuan luar."
  data={[
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: -3 + 1.5 * Math.cos(angle),
          y: 1.5 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: 3 + 2.5 * Math.cos(angle),
          y: 2.5 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: [
        { x: -3, y: 0, z: 0 },
        { x: 3, y: 0, z: 0 },
      ],
      color: getColor("ORANGE"),
      showPoints: true,
      labels: [
        { text: "A", at: 0, offset: [-0.5, -0.5, 0] },
        { text: "B", at: 1, offset: [0.5, -0.5, 0] },
      ],
    },
        {
      points: (() => {
        const O1 = { x: -3, y: 0 };
        const O2 = { x: 3, y: 0 };
        const r1 = 1.5;
        const r2 = 2.5;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        // Calculate the angle for external tangent
        const sin_alpha = (r2 - r1) / d;
        const cos_alpha = Math.sqrt(1 - sin_alpha * sin_alpha);

        // Direction from O1 to O2
        const dx = O2.x - O1.x;
        const dy = O2.y - O1.y;

        // Normalize direction
        const ux = dx / d;
        const uy = dy / d;

        // Perpendicular direction (rotated 90 degrees)
        const vx = -uy;
        const vy = ux;

        // First tangent line (upper)
        // Tangent point on first circle
        const T1x = O1.x + r1 * (sin_alpha * ux + cos_alpha * vx);
        const T1y = O1.y + r1 * (sin_alpha * uy + cos_alpha * vy);

        // Tangent point on second circle
        const T2x = O2.x + r2 * (sin_alpha * ux + cos_alpha * vx);
        const T2y = O2.y + r2 * (sin_alpha * uy + cos_alpha * vy);

        return [
          // hard code little bit to make it look better
          { x: T1x - 0.25, y: T1y, z: 0 },
          { x: T2x - 0.45, y: T2y, z: 0 },
        ];
      })(),
      color: getColor("CYAN"),
      showPoints: true,
      labels: [
        { text: "P", at: 0, offset: [-0.5, 0.5, 0] },
        { text: "Q", at: 1, offset: [0.5, 0.5, 0] },
      ],
    },
    {
      points: (() => {
        const O1 = { x: -3, y: 0 };
        const O2 = { x: 3, y: 0 };
        const r1 = 1.5;
        const r2 = 2.5;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        // Calculate the angle for external tangent
        const sin_alpha = (r2 - r1) / d;
        const cos_alpha = Math.sqrt(1 - sin_alpha * sin_alpha);

        // Direction from O1 to O2
        const dx = O2.x - O1.x;
        const dy = O2.y - O1.y;

        // Normalize direction
        const ux = dx / d;
        const uy = dy / d;

        // Perpendicular direction (rotated 90 degrees)
        const vx = -uy;
        const vy = ux;

        // Second tangent line (lower)
        // Tangent point on first circle
        const T1x = O1.x + r1 * (sin_alpha * ux - cos_alpha * vx);
        const T1y = O1.y + r1 * (sin_alpha * uy - cos_alpha * vy);

        // Tangent point on second circle
        const T2x = O2.x + r2 * (sin_alpha * ux - cos_alpha * vx);
        const T2y = O2.y + r2 * (sin_alpha * uy - cos_alpha * vy);

        return [
          // hard code little bit to make it look better
          { x: T1x - 0.25, y: T1y, z: 0 },
          { x: T2x - 0.45, y: T2y, z: 0 },
        ];
      })(),
      color: getColor("TEAL"),
      showPoints: true,
      labels: [
        { text: "R", at: 0, offset: [-0.5, -0.5, 0] },
        { text: "S", at: 1, offset: [0.5, -0.5, 0] },
      ],
    },

]}
cameraPosition={[0, 0, 12]}
showZAxis={false}
/>

**Penyelesaian:**

<div className="flex flex-col gap-4">
  <BlockMath math="d = \sqrt{(3-(-3))^2 + (0-0)^2} = \sqrt{36} = 6" />
  <BlockMath math="l = \sqrt{d^2 - (r_2 - r_1)^2}" />
  <BlockMath math="l = \sqrt{6^2 - (2.5 - 1.5)^2}" />
  <BlockMath math="l = \sqrt{36 - 1}" />
  <BlockMath math="l = \sqrt{35}" />
</div>

Jadi, panjang garis singgung persekutuan luar adalah <InlineMath math="\sqrt{35}" /> satuan.

## Konsep Garis Singgung Persekutuan Dalam

Garis singgung persekutuan dalam adalah garis yang menyinggung kedua lingkaran dari sisi yang berlawanan dan memotong garis yang menghubungkan kedua pusat lingkaran.

<LineEquation
  title="Garis Singgung Persekutuan Dalam"
  description="Dua garis singgung persekutuan dalam pada dua lingkaran."
  data={[
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: -4 + 2 * Math.cos(angle),
          y: 2 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: 4 + 2 * Math.cos(angle),
          y: 2 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: [
        { x: -4, y: 0, z: 0 },
        { x: 4, y: 0, z: 0 },
      ],
      color: getColor("ORANGE"),
      showPoints: true,
      labels: [
        { text: "A", at: 0, offset: [-0.5, -0.5, 0] },
        { text: "B", at: 1, offset: [0.5, -0.5, 0] },
      ],
    },
    {
      points: (() => {
        const O1 = { x: -4, y: 0 };
        const O2 = { x: 4, y: 0 };
        const r1 = 2;
        const r2 = 2;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        const alpha = Math.asin((r1 + r2) / d);
        const theta = Math.atan2(O2.y - O1.y, O2.x - O1.x);

        const T1x = O1.x + r1 * Math.cos(theta + Math.PI / 2 - alpha);
        const T1y = O1.y + r1 * Math.sin(theta + Math.PI / 2 - alpha);

        const T2x = O2.x + r2 * Math.cos(theta + Math.PI / 2 - alpha + Math.PI);
        const T2y = O2.y + r2 * Math.sin(theta + Math.PI / 2 - alpha + Math.PI);

        const dx = T2x - T1x;
        const dy = T2y - T1y;
        const len = Math.sqrt(dx * dx + dy * dy);
        const ux = dx / len;
        const uy = dy / len;

        return [
          { x: T1x - 3 * ux, y: T1y - 3 * uy, z: 0 },
          { x: T2x + 3 * ux, y: T2y + 3 * uy, z: 0 },
        ];
      })(),
      color: getColor("PINK"),
      showPoints: false,
      labels: [{ text: "h₁", at: 0, offset: [-1, 0.5, 0] }],
    },
    {
      points: (() => {
        const O1 = { x: -4, y: 0 };
        const O2 = { x: 4, y: 0 };
        const r1 = 2;
        const r2 = 2;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        const alpha = Math.asin((r1 + r2) / d);
        const theta = Math.atan2(O2.y - O1.y, O2.x - O1.x);

        const T1x = O1.x + r1 * Math.cos(theta - Math.PI / 2 + alpha);
        const T1y = O1.y + r1 * Math.sin(theta - Math.PI / 2 + alpha);

        const T2x = O2.x + r2 * Math.cos(theta - Math.PI / 2 + alpha + Math.PI);
        const T2y = O2.y + r2 * Math.sin(theta - Math.PI / 2 + alpha + Math.PI);

        const dx = T2x - T1x;
        const dy = T2y - T1y;
        const len = Math.sqrt(dx * dx + dy * dy);
        const ux = dx / len;
        const uy = dy / len;

        return [
          { x: T1x - 3 * ux, y: T1y - 3 * uy, z: 0 },
          { x: T2x + 3 * ux, y: T2y + 3 * uy, z: 0 },
        ];
      })(),
      color: getColor("AMBER"),
      showPoints: false,
      labels: [{ text: "h₂", at: 0, offset: [-1, -0.5, 0] }],
    },

]}
cameraPosition={[0, 0, 15]}
showZAxis={false}
/>

### Rumus Panjang Garis Singgung Persekutuan Dalam

Panjang garis singgung persekutuan dalam:

<BlockMath math="l = \sqrt{d^2 - (r_1 + r_2)^2}" />

**Syarat:** Garis singgung persekutuan dalam hanya ada jika <InlineMath math="d > r_1 + r_2" /> (kedua lingkaran tidak berpotongan).

### Mencari Panjang Garis Singgung Persekutuan Dalam

Dua lingkaran masing-masing berpusat di <InlineMath math="P(-5, 0)" /> dengan jari-jari 2 dan <InlineMath math="Q(5, 0)" /> dengan jari-jari 3. Tentukan panjang garis singgung persekutuan dalam!

<LineEquation
  title={
    <>
      Lingkaran dengan <InlineMath math="r_1 = 2" /> dan{" "}
      <InlineMath math="r_2 = 3" />
    </>
  }
  description="Visualisasi garis singgung persekutuan dalam."
  data={[
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: -5 + 2 * Math.cos(angle),
          y: 2 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: 5 + 3 * Math.cos(angle),
          y: 3 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: [
        { x: -5, y: 0, z: 0 },
        { x: 5, y: 0, z: 0 },
      ],
      color: getColor("ORANGE"),
      showPoints: true,
      labels: [
        { text: "P", at: 0, offset: [-0.5, -0.5, 0] },
        { text: "Q", at: 1, offset: [0.5, -0.5, 0] },
      ],
    },
    {
      points: (() => {
        const O1 = { x: -5, y: 0 };
        const O2 = { x: 5, y: 0 };
        const r1 = 2;
        const r2 = 3;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        const alpha = Math.asin((r1 + r2) / d);
        const theta = Math.atan2(O2.y - O1.y, O2.x - O1.x);

        const T1x = O1.x + r1 * Math.cos(theta + Math.PI / 2 - alpha);
        const T1y = O1.y + r1 * Math.sin(theta + Math.PI / 2 - alpha);

        const T2x = O2.x + r2 * Math.cos(theta + Math.PI / 2 - alpha + Math.PI);
        const T2y = O2.y + r2 * Math.sin(theta + Math.PI / 2 - alpha + Math.PI);

        return [
          { x: T1x, y: T1y, z: 0 },
          { x: T2x, y: T2y, z: 0 },
        ];
      })(),
      color: getColor("PINK"),
      showPoints: true,
      labels: [
        { text: "E", at: 0, offset: [-0.5, 0.5, 0] },
        { text: "F", at: 1, offset: [0.5, -0.5, 0] },
      ],
    },
    {
      points: (() => {
        const O1 = { x: -5, y: 0 };
        const O2 = { x: 5, y: 0 };
        const r1 = 2;
        const r2 = 3;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        const alpha = Math.asin((r1 + r2) / d);
        const theta = Math.atan2(O2.y - O1.y, O2.x - O1.x);

        const T1x = O1.x + r1 * Math.cos(theta - Math.PI / 2 + alpha);
        const T1y = O1.y + r1 * Math.sin(theta - Math.PI / 2 + alpha);

        const T2x = O2.x + r2 * Math.cos(theta - Math.PI / 2 + alpha + Math.PI);
        const T2y = O2.y + r2 * Math.sin(theta - Math.PI / 2 + alpha + Math.PI);

        return [
          { x: T1x, y: T1y, z: 0 },
          { x: T2x, y: T2y, z: 0 },
        ];
      })(),
      color: getColor("AMBER"),
      showPoints: true,
      labels: [
        { text: "G", at: 0, offset: [-0.5, -0.5, 0] },
        { text: "H", at: 1, offset: [0.5, 0.5, 0] },
      ],
    },

]}
cameraPosition={[0, 0, 18]}
showZAxis={false}
/>

**Penyelesaian:**

Pertama, periksa apakah garis singgung persekutuan dalam ada:

<div className="flex flex-col gap-4">
  <BlockMath math="d = \sqrt{(5-(-5))^2 + (0-0)^2} = \sqrt{100} = 10" />
  <BlockMath math="r_1 + r_2 = 2 + 3 = 5" />
  <BlockMath math="d = 10 > 5 = r_1 + r_2 \space \checkmark" />
</div>

Karena syarat terpenuhi, maka:

<div className="flex flex-col gap-4">
  <BlockMath math="l = \sqrt{d^2 - (r_1 + r_2)^2}" />
  <BlockMath math="l = \sqrt{10^2 - 5^2}" />
  <BlockMath math="l = \sqrt{100 - 25}" />
  <BlockMath math="l = \sqrt{75}" />
  <BlockMath math="l = 5\sqrt{3}" />
</div>

Jadi, panjang garis singgung persekutuan dalam adalah <InlineMath math="5\sqrt{3}" /> satuan.

## Lingkaran dengan Jari-jari Sama

Ketika dua lingkaran memiliki jari-jari yang sama (<InlineMath math="r_1 = r_2 = r" />), terdapat sifat khusus:

### Garis Singgung Persekutuan Luar

<LineEquation
  title="Garis Singgung Persekutuan Luar untuk Jari-jari Sama"
  description="Garis singgung persekutuan luar sejajar dengan garis pusat."
  data={[
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: -3 + 2 * Math.cos(angle),
          y: 2 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: 3 + 2 * Math.cos(angle),
          y: 2 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: [
        { x: -3, y: 0, z: 0 },
        { x: 3, y: 0, z: 0 },
      ],
      color: getColor("ORANGE"),
      showPoints: true,
      labels: [
        { text: "O₁", at: 0, offset: [-0.5, -0.5, 0] },
        { text: "O₂", at: 1, offset: [0.5, -0.5, 0] },
      ],
    },
    {
      points: [
        { x: -3, y: 2, z: 0 },
        { x: 3, y: 2, z: 0 },
      ],
      color: getColor("CYAN"),
      showPoints: false,
      smooth: false,
    },
    {
      points: [
        { x: -3, y: -2, z: 0 },
        { x: 3, y: -2, z: 0 },
      ],
      color: getColor("TEAL"),
      showPoints: false,
      smooth: false,
    },
  ]}
  cameraPosition={[0, 0, 12]}
  showZAxis={false}
/>

Untuk <InlineMath math="r_1 = r_2" />:

- Garis singgung persekutuan luar **sejajar** dengan garis yang menghubungkan kedua pusat
- Panjang garis singgung persekutuan luar = <InlineMath math="d" /> (jarak antara pusat)

## Kasus Berbagai Posisi Lingkaran

Tentukan panjang garis singgung persekutuan luar dan dalam untuk lingkaran-lingkaran berikut:

### Lingkaran Berjauhan

Lingkaran pertama berpusat di <InlineMath math="(-6, 0)" /> dengan jari-jari 1, lingkaran kedua berpusat di <InlineMath math="(6, 0)" /> dengan jari-jari 2.

<LineEquation
  title="Kasus: Lingkaran Berjauhan"
  description="Kedua jenis garis singgung persekutuan ada."
  data={[
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: -6 + 1 * Math.cos(angle),
          y: 1 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: 6 + 2 * Math.cos(angle),
          y: 2 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
        {
      points: (() => {
        const O1 = { x: -6, y: 0 };
        const O2 = { x: 6, y: 0 };
        const r1 = 1;
        const r2 = 2;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        // Calculate the angle for external tangent
        const sin_alpha = (r2 - r1) / d;
        const cos_alpha = Math.sqrt(1 - sin_alpha * sin_alpha);

        // Direction from O1 to O2
        const dx = O2.x - O1.x;
        const dy = O2.y - O1.y;

        // Normalize direction
        const ux = dx / d;
        const uy = dy / d;

        // Perpendicular direction (rotated 90 degrees)
        const vx = -uy;
        const vy = ux;

        // First tangent line (upper)
        // Tangent point on first circle
        const T1x = O1.x + r1 * (sin_alpha * ux + cos_alpha * vx);
        const T1y = O1.y + r1 * (sin_alpha * uy + cos_alpha * vy);

        // Tangent point on second circle
        const T2x = O2.x + r2 * (sin_alpha * ux + cos_alpha * vx);
        const T2y = O2.y + r2 * (sin_alpha * uy + cos_alpha * vy);

        const tdx = T2x - T1x;
        const tdy = T2y - T1y;
        const tlen = Math.sqrt(tdx * tdx + tdy * tdy);
        const tux = tdx / tlen;
        const tuy = tdy / tlen;

        return [
          { x: T1x - 2 * tux, y: T1y - 2 * tuy, z: 0 },
          { x: T2x + 2 * tux, y: T2y + 2 * tuy, z: 0 },
        ];
      })(),
      color: getColor("CYAN"),
      showPoints: false,
    },
    {
      points: (() => {
        const O1 = { x: -6, y: 0 };
        const O2 = { x: 6, y: 0 };
        const r1 = 1;
        const r2 = 2;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        // Calculate the angle for external tangent
        const sin_alpha = (r2 - r1) / d;
        const cos_alpha = Math.sqrt(1 - sin_alpha * sin_alpha);

        // Direction from O1 to O2
        const dx = O2.x - O1.x;
        const dy = O2.y - O1.y;

        // Normalize direction
        const ux = dx / d;
        const uy = dy / d;

        // Perpendicular direction (rotated 90 degrees)
        const vx = -uy;
        const vy = ux;

        // Second tangent line (lower)
        // Tangent point on first circle
        const T1x = O1.x + r1 * (sin_alpha * ux - cos_alpha * vx);
        const T1y = O1.y + r1 * (sin_alpha * uy - cos_alpha * vy);

        // Tangent point on second circle
        const T2x = O2.x + r2 * (sin_alpha * ux - cos_alpha * vx);
        const T2y = O2.y + r2 * (sin_alpha * uy - cos_alpha * vy);

        const tdx = T2x - T1x;
        const tdy = T2y - T1y;
        const tlen = Math.sqrt(tdx * tdx + tdy * tdy);
        const tux = tdx / tlen;
        const tuy = tdy / tlen;

        return [
          { x: T1x - 2 * tux, y: T1y - 2 * tuy, z: 0 },
          { x: T2x + 2 * tux, y: T2y + 2 * tuy, z: 0 },
        ];
      })(),
      color: getColor("TEAL"),
      showPoints: false,
    },
    {
      points: (() => {
        const O1 = { x: -6, y: 0 };
        const O2 = { x: 6, y: 0 };
        const r1 = 1;
        const r2 = 2;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        const alpha = Math.asin((r1 + r2) / d);
        const theta = Math.atan2(O2.y - O1.y, O2.x - O1.x);

        const T1x = O1.x + r1 * Math.cos(theta + Math.PI / 2 - alpha);
        const T1y = O1.y + r1 * Math.sin(theta + Math.PI / 2 - alpha);

        const T2x = O2.x + r2 * Math.cos(theta + Math.PI / 2 - alpha + Math.PI);
        const T2y = O2.y + r2 * Math.sin(theta + Math.PI / 2 - alpha + Math.PI);

        const dx = T2x - T1x;
        const dy = T2y - T1y;
        const len = Math.sqrt(dx * dx + dy * dy);
        const ux = dx / len;
        const uy = dy / len;

        return [
          { x: T1x - 1 * ux, y: T1y - 1 * uy, z: 0 },
          { x: T2x + 1 * ux, y: T2y + 1 * uy, z: 0 },
        ];
      })(),
      color: getColor("PINK"),
      showPoints: false,
    },
    {
      points: (() => {
        const O1 = { x: -6, y: 0 };
        const O2 = { x: 6, y: 0 };
        const r1 = 1;
        const r2 = 2;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        const alpha = Math.asin((r1 + r2) / d);
        const theta = Math.atan2(O2.y - O1.y, O2.x - O1.x);

        const T1x = O1.x + r1 * Math.cos(theta - Math.PI / 2 + alpha);
        const T1y = O1.y + r1 * Math.sin(theta - Math.PI / 2 + alpha);

        const T2x = O2.x + r2 * Math.cos(theta - Math.PI / 2 + alpha + Math.PI);
        const T2y = O2.y + r2 * Math.sin(theta - Math.PI / 2 + alpha + Math.PI);

        const dx = T2x - T1x;
        const dy = T2y - T1y;
        const len = Math.sqrt(dx * dx + dy * dy);
        const ux = dx / len;
        const uy = dy / len;

        return [
          { x: T1x - 1 * ux, y: T1y - 1 * uy, z: 0 },
          { x: T2x + 1 * ux, y: T2y + 1 * uy, z: 0 },
        ];
      })(),
      color: getColor("AMBER"),
      showPoints: false,
    },

]}
cameraPosition={[0, 0, 18]}
showZAxis={false}
/>

**Penyelesaian:**

<div className="flex flex-col gap-4">
  <BlockMath math="d = \sqrt{(6-(-6))^2 + (0-0)^2} = 12" />
  <BlockMath math="l_{luar} = \sqrt{12^2 - (2-1)^2} = \sqrt{144 - 1} = \sqrt{143}" />
  <BlockMath math="l_{dalam} = \sqrt{12^2 - (1+2)^2} = \sqrt{144 - 9} = \sqrt{135} = 3\sqrt{15}" />
</div>

### Lingkaran Berdekatan

Lingkaran pertama berpusat di <InlineMath math="(-2, 0)" /> dengan jari-jari 1.5, lingkaran kedua berpusat di <InlineMath math="(2, 0)" /> dengan jari-jari 1.5.

<LineEquation
  title="Kasus: Lingkaran Berdekatan dengan Jari-jari Sama"
  description="Garis singgung persekutuan luar sejajar, dalam berpotongan di tengah."
  data={[
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: -2 + 1.5 * Math.cos(angle),
          y: 1.5 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: Array.from({ length: 361 }, (_, i) => {
        const angle = (i * Math.PI) / 180;
        return {
          x: 2 + 1.5 * Math.cos(angle),
          y: 1.5 * Math.sin(angle),
          z: 0,
        };
      }),
      color: getColor("PURPLE"),
      showPoints: false,
    },
    {
      points: [
        { x: -5, y: 1.5, z: 0 },
        { x: 5, y: 1.5, z: 0 },
      ],
      color: getColor("CYAN"),
      showPoints: false,
      smooth: false,
    },
    {
      points: [
        { x: -5, y: -1.5, z: 0 },
        { x: 5, y: -1.5, z: 0 },
      ],
      color: getColor("TEAL"),
      showPoints: false,
      smooth: false,
    },
    {
      points: (() => {
        const O1 = { x: -2, y: 0 };
        const O2 = { x: 2, y: 0 };
        const r1 = 1.5;
        const r2 = 1.5;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        const alpha = Math.asin((r1 + r2) / d);
        const theta = Math.atan2(O2.y - O1.y, O2.x - O1.x);

        const T1x = O1.x + r1 * Math.cos(theta + Math.PI / 2 - alpha);
        const T1y = O1.y + r1 * Math.sin(theta + Math.PI / 2 - alpha);

        const T2x = O2.x + r2 * Math.cos(theta + Math.PI / 2 - alpha + Math.PI);
        const T2y = O2.y + r2 * Math.sin(theta + Math.PI / 2 - alpha + Math.PI);

        const dx = T2x - T1x;
        const dy = T2y - T1y;
        const len = Math.sqrt(dx * dx + dy * dy);
        const ux = dx / len;
        const uy = dy / len;

        return [
          { x: T1x - 2 * ux, y: T1y - 2 * uy, z: 0 },
          { x: T2x + 2 * ux, y: T2y + 2 * uy, z: 0 },
        ];
      })(),
      color: getColor("PINK"),
      showPoints: false,
    },
    {
      points: (() => {
        const O1 = { x: -2, y: 0 };
        const O2 = { x: 2, y: 0 };
        const r1 = 1.5;
        const r2 = 1.5;
        const d = Math.sqrt((O2.x - O1.x) ** 2 + (O2.y - O1.y) ** 2);

        const alpha = Math.asin((r1 + r2) / d);
        const theta = Math.atan2(O2.y - O1.y, O2.x - O1.x);

        const T1x = O1.x + r1 * Math.cos(theta - Math.PI / 2 + alpha);
        const T1y = O1.y + r1 * Math.sin(theta - Math.PI / 2 + alpha);

        const T2x = O2.x + r2 * Math.cos(theta - Math.PI / 2 + alpha + Math.PI);
        const T2y = O2.y + r2 * Math.sin(theta - Math.PI / 2 + alpha + Math.PI);

        const dx = T2x - T1x;
        const dy = T2y - T1y;
        const len = Math.sqrt(dx * dx + dy * dy);
        const ux = dx / len;
        const uy = dy / len;

        return [
          { x: T1x - 2 * ux, y: T1y - 2 * uy, z: 0 },
          { x: T2x + 2 * ux, y: T2y + 2 * uy, z: 0 },
        ];
      })(),
      color: getColor("AMBER"),
      showPoints: false,
    },

]}
cameraPosition={[0, 0, 10]}
showZAxis={false}
/>

**Penyelesaian:**

<div className="flex flex-col gap-4">
  <BlockMath math="d = \sqrt{(2-(-2))^2 + (0-0)^2} = 4" />
  <BlockMath math="r_1 = r_2 = 1.5" />
  <BlockMath math="l_{luar} = d = 4" />
  <BlockMath math="l_{dalam} = \sqrt{4^2 - (1.5+1.5)^2} = \sqrt{16 - 9} = \sqrt{7}" />
</div>

## Latihan Soal

1. Dua lingkaran masing-masing berpusat di <InlineMath math="A(-4, 0)" /> dengan jari-jari 2 dan <InlineMath math="B(4, 0)" /> dengan jari-jari 3. Tentukan:

   - Panjang garis singgung persekutuan luar
   - Panjang garis singgung persekutuan dalam

2. Lingkaran pertama memiliki pusat <InlineMath math="(0, 0)" /> dengan jari-jari 4, lingkaran kedua memiliki pusat <InlineMath math="(10, 0)" /> dengan jari-jari 2. Hitunglah panjang kedua jenis garis singgung persekutuan!

3. Dua lingkaran identik masing-masing berjari-jari 3 cm. Jika panjang garis singgung persekutuan dalam adalah 8 cm, tentukan jarak antara kedua pusat lingkaran!

4. Lingkaran <InlineMath math="A" /> berpusat di <InlineMath math="(-5, 0)" /> dengan jari-jari <InlineMath math="r" />, dan lingkaran <InlineMath math="B" /> berpusat di <InlineMath math="(7, 0)" /> dengan jari-jari <InlineMath math="2r" />. Jika panjang garis singgung persekutuan luar adalah <InlineMath math="4\sqrt{8}" />, tentukan nilai <InlineMath math="r" />!

5. Tentukan syarat agar dua lingkaran memiliki:
   - Tepat dua garis singgung persekutuan
   - Tepat tiga garis singgung persekutuan
   - Tepat empat garis singgung persekutuan

### Kunci Jawaban

1. **Menghitung panjang garis singgung persekutuan**

   <div className="flex flex-col gap-4">
     <BlockMath math="d = \sqrt{(4-(-4))^2 + (0-0)^2} = 8" />
     <BlockMath math="l_{luar} = \sqrt{8^2 - (3-2)^2} = \sqrt{64 - 1} = \sqrt{63} = 3\sqrt{7}" />
     <BlockMath math="l_{dalam} = \sqrt{8^2 - (2+3)^2} = \sqrt{64 - 25} = \sqrt{39}" />
   </div>

2. **Lingkaran dengan pusat berbeda**

   <div className="flex flex-col gap-4">
     <BlockMath math="d = \sqrt{(10-0)^2 + (0-0)^2} = 10" />
     <BlockMath math="l_{luar} = \sqrt{10^2 - (4-2)^2} = \sqrt{100 - 4} = \sqrt{96} = 4\sqrt{6}" />
     <BlockMath math="l_{dalam} = \sqrt{10^2 - (4+2)^2} = \sqrt{100 - 36} = \sqrt{64} = 8" />
   </div>

3. **Mencari jarak pusat dari panjang garis singgung dalam**

   Diketahui: <InlineMath math="r_1 = r_2 = 3" />, <InlineMath math="l_{dalam} = 8" />

   <div className="flex flex-col gap-4">
     <BlockMath math="l = \sqrt{d^2 - (r_1 + r_2)^2}" />
     <BlockMath math="8 = \sqrt{d^2 - 6^2}" />
     <BlockMath math="64 = d^2 - 36" />
     <BlockMath math="d^2 = 100" />
     <BlockMath math="d = 10 \text{ cm}" />
   </div>

4. **Mencari nilai r**

   Diketahui: <InlineMath math="d = 12" />, <InlineMath math="r_1 = r" />, <InlineMath math="r_2 = 2r" />, <InlineMath math="l_{luar} = 4\sqrt{8}" />

   <div className="flex flex-col gap-4">
     <BlockMath math="4\sqrt{8} = \sqrt{12^2 - (2r - r)^2}" />
     <BlockMath math="16 \cdot 8 = 144 - r^2" />
     <BlockMath math="128 = 144 - r^2" />
     <BlockMath math="r^2 = 16" />
     <BlockMath math="r = 4" />
   </div>

5. **Syarat jumlah garis singgung persekutuan**

   - **Tepat 2 garis singgung**: Kedua lingkaran berpotongan di dua titik
   - **Tepat 3 garis singgung**: Kedua lingkaran bersinggungan (dalam atau luar)
   - **Tepat 4 garis singgung**: Kedua lingkaran terpisah (tidak berpotongan)
