{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PHYS 216 — Point Charges in Three Dimensions\n",
    "\n",
    "## Problem 56\n",
    "\n",
    "Point charges $Q_1=2.0\\,\\mu\\text{C}$ and $Q_2=4.0\\,\\mu\\text{C}$ are located at\n",
    "\n",
    "$$\\vec r_1=(4.0\\hat{\\mathbf i}-2.0\\hat{\\mathbf j}+5.0\\hat{\\mathbf k})\\,\\text{m}$$\n",
    "\n",
    "and\n",
    "\n",
    "$$\\vec r_2=(8.0\\hat{\\mathbf i}+5.0\\hat{\\mathbf j}-9.0\\hat{\\mathbf k})\\,\\text{m}.$$\n",
    "\n",
    "Find the force of $Q_2$ on $Q_1$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Direction of the separation vector\n",
    "\n",
    "Because we want the force **on $Q_1$ due to $Q_2$**, the required displacement vector points from $Q_2$ to $Q_1$:\n",
    "\n",
    "$$\\vec r_{21}=\\vec r_1-\\vec r_2.$$\n",
    "\n",
    "Coulomb's law in vector form is\n",
    "\n",
    "$$\\vec F_{2\\to1}=k\\frac{Q_1Q_2}{|\\vec r_{21}|^3}\\vec r_{21}.$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# Coulomb constant and charges (SI units)\n",
    "k = 8.987_551_792_3e9       # N m^2/C^2\n",
    "Q1 = 2.0e-6                 # C\n",
    "Q2 = 4.0e-6                 # C\n",
    "\n",
    "# Position vectors (m)\n",
    "r1 = np.array([4.0, -2.0, 5.0])\n",
    "r2 = np.array([8.0,  5.0, -9.0])\n",
    "\n",
    "print(f'Q1 = {Q1:.2e} C at r1 = {r1} m')\n",
    "print(f'Q2 = {Q2:.2e} C at r2 = {r2} m')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Vector from Q2 to Q1\n",
    "r21 = r1 - r2\n",
    "distance = np.linalg.norm(r21)\n",
    "r21_hat = r21 / distance\n",
    "\n",
    "print(f'r21 = r1 - r2 = {r21} m')\n",
    "print(f'|r21| = {distance:.6f} m')\n",
    "print(f'r21_hat = {r21_hat}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, $\\vec r_{21}=(-4,-7,14)\\,\\text{m}$ and $|\\vec r_{21}|=\\sqrt{261}\\,\\text{m}$. Both charges are positive, so the force is repulsive and must point from $Q_2$ toward $Q_1$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Coulomb force of Q2 on Q1\n",
    "F21 = k * Q1 * Q2 * r21 / distance**3\n",
    "F_magnitude = np.linalg.norm(F21)\n",
    "\n",
    "print('Force components:')\n",
    "print(f'F_2->1 = ({F21[0]:.6e} i {F21[1]:+.6e} j {F21[2]:+.6e} k) N')\n",
    "print(f'|F_2->1| = {F_magnitude:.6e} N')\n",
    "print(f'             = {F_magnitude*1e6:.3f} microN')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Visualize the geometry\n",
    "\n",
    "The red arrow begins at $Q_1$ and shows the direction of the force on $Q_1$. Its displayed length is scaled for visibility; its physical magnitude is reported above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(figsize=(9, 7))\n",
    "ax = fig.add_subplot(111, projection='3d')\n",
    "\n",
    "# Coordinate axes\n",
    "ax.plot([-2, 12], [0, 0], [0, 0], color='0.65', lw=1)\n",
    "ax.plot([0, 0], [-10, 8], [0, 0], color='0.65', lw=1)\n",
    "ax.plot([0, 0], [0, 0], [-12, 10], color='0.65', lw=1)\n",
    "\n",
    "# Charges\n",
    "ax.scatter(*r1, s=130, color='#1769aa', edgecolor='white', linewidth=1.5, label=r'$Q_1=2.0\\,\\mu C$')\n",
    "ax.scatter(*r2, s=160, color='#ef6c00', edgecolor='white', linewidth=1.5, label=r'$Q_2=4.0\\,\\mu C$')\n",
    "ax.text(*(r1 + np.array([0.3, 0.3, 0.4])), '$Q_1$', fontsize=13)\n",
    "ax.text(*(r2 + np.array([0.3, 0.3, 0.4])), '$Q_2$', fontsize=13)\n",
    "\n",
    "# Dashed separation line from Q2 to Q1\n",
    "ax.plot([r2[0], r1[0]], [r2[1], r1[1]], [r2[2], r1[2]], '--', color='#5f6b7a', lw=2, label=r'$\\vec r_{21}$')\n",
    "\n",
    "# Force direction at Q1, scaled only for display\n",
    "display_length = 6.0\n",
    "force_display = r21_hat * display_length\n",
    "ax.quiver(*r1, *force_display, color='#c62828', linewidth=3, arrow_length_ratio=0.18)\n",
    "ax.text(*(r1 + force_display + np.array([0.2, 0.2, 0.2])), r'$\\vec F_{2\\to1}$', color='#c62828', fontsize=13)\n",
    "\n",
    "ax.set_xlabel('x (m)', labelpad=10)\n",
    "ax.set_ylabel('y (m)', labelpad=10)\n",
    "ax.set_zlabel('z (m)', labelpad=10)\n",
    "ax.set_title('Force of $Q_2$ on $Q_1$', pad=18, fontsize=15, weight='bold')\n",
    "ax.set_xlim(-2, 12)\n",
    "ax.set_ylim(-10, 8)\n",
    "ax.set_zlim(-12, 10)\n",
    "ax.set_box_aspect((14, 18, 22))\n",
    "ax.view_init(elev=24, azim=-55)\n",
    "ax.legend(loc='upper left')\n",
    "ax.grid(True, alpha=0.25)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Final answer\n",
    "\n",
    "$$\\boxed{\\vec F_{2\\to1}=(-6.82\\times10^{-5}\\hat{\\mathbf i}-1.19\\times10^{-4}\\hat{\\mathbf j}+2.39\\times10^{-4}\\hat{\\mathbf k})\\,\\text{N}}$$\n",
    "\n",
    "with magnitude\n",
    "\n",
    "$$\\boxed{|\\vec F_{2\\to1}|=2.75\\times10^{-4}\\,\\text{N}=275\\,\\mu\\text{N}.}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Try another case\n",
    "Change `Q1`, `Q2`, `r1`, or `r2` in the first code cell, then run all cells again. If one charge is negative, the force direction reverses automatically because the product $Q_1Q_2$ becomes negative."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
