-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
183 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"16.97\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"import math\n", | ||
"\n", | ||
"# 计算两点之间的欧几里得距离\n", | ||
"def distance(p1, p2):\n", | ||
" return math.sqrt((p2[0] - p1[0])**2 + (p2[1] - p1[1])**2 + (p2[2] - p1[2])**2)\n", | ||
"\n", | ||
"# 计算最短距离\n", | ||
"def calculate_shortest_distance(A, B, C, R):\n", | ||
" dAC = distance(A, C)\n", | ||
" dBC = distance(B, C)\n", | ||
" dAB = distance(A, B)\n", | ||
" \n", | ||
" # 如果A到C或B到C的距离小于等于球体半径,说明A或B在球体内\n", | ||
" if dAC <= R or dBC <= R:\n", | ||
" return -1 # 特殊情况处理(可以根据题意调整)\n", | ||
" \n", | ||
" # 如果AB的直线不穿过球体,直接返回欧几里得距离\n", | ||
" return dAB\n", | ||
"\n", | ||
"# 读取输入\n", | ||
"A = list(map(float, input().split()))\n", | ||
"B = list(map(float, input().split()))\n", | ||
"C = list(map(float, input().split()))\n", | ||
"R = float(input())\n", | ||
"\n", | ||
"# 计算并输出最短距离,保留两位小数\n", | ||
"result = calculate_shortest_distance(A, B, C, R)\n", | ||
"print(f\"{result:.2f}\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"19.71\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"import math\n", | ||
"\n", | ||
"def read_point():\n", | ||
" return list(map(int, input().strip().split()))\n", | ||
"\n", | ||
"def distance(p1, p2):\n", | ||
" return math.hypot(p1[0]-p2[0], p1[1]-p2[1])\n", | ||
"\n", | ||
"def distance_point_to_line(A, B, C):\n", | ||
" # A, B, C are tuples (x, y)\n", | ||
" cross = abs( (B[0]-A[0])*(A[1]-C[1]) - (B[1]-A[1])*(A[0]-C[0]) )\n", | ||
" dist = cross / distance(A, B)\n", | ||
" return dist\n", | ||
"\n", | ||
"def tangent_points(P, C, R):\n", | ||
" # P and C are tuples (x, y)\n", | ||
" dx = P[0] - C[0]\n", | ||
" dy = P[1] - C[1]\n", | ||
" dist = math.hypot(dx, dy)\n", | ||
" if dist < R:\n", | ||
" return [] # No tangent\n", | ||
" elif dist == R:\n", | ||
" return [P] # One tangent point (the point itself)\n", | ||
" else:\n", | ||
" angle_PC = math.atan2(dy, dx)\n", | ||
" alpha = math.acos(R / dist)\n", | ||
" t1 = angle_PC + alpha\n", | ||
" t2 = angle_PC - alpha\n", | ||
" tp1 = (C[0] + R * math.cos(t1), C[1] + R * math.sin(t1))\n", | ||
" tp2 = (C[0] + R * math.cos(t2), C[1] + R * math.sin(t2))\n", | ||
" return [tp1, tp2]\n", | ||
"\n", | ||
"def angle_between(C, P1, P2):\n", | ||
" # C is center, P1 and P2 are points on circle\n", | ||
" v1x = P1[0] - C[0]\n", | ||
" v1y = P1[1] - C[1]\n", | ||
" v2x = P2[0] - C[0]\n", | ||
" v2y = P2[1] - C[1]\n", | ||
" dot = v1x * v2x + v1y * v2y\n", | ||
" mag1 = math.hypot(v1x, v1y)\n", | ||
" mag2 = math.hypot(v2x, v2y)\n", | ||
" if mag1 ==0 or mag2==0:\n", | ||
" return 0\n", | ||
" cos_theta = dot / (mag1 * mag2)\n", | ||
" # Clamp due to floating point\n", | ||
" cos_theta = max(min(cos_theta,1), -1)\n", | ||
" theta = math.acos(cos_theta)\n", | ||
" return theta\n", | ||
"\n", | ||
"def compute_path(A, B, C, R):\n", | ||
" # A, B, C are tuples (x, y)\n", | ||
" dist_AB = distance(A, B)\n", | ||
" dist_to_line = distance_point_to_line(A, B, C)\n", | ||
" if dist_to_line >= R:\n", | ||
" return dist_AB\n", | ||
" # Compute tangent points\n", | ||
" tangents_A = tangent_points(A, C, R)\n", | ||
" tangents_B = tangent_points(B, C, R)\n", | ||
" if not tangents_A or not tangents_B:\n", | ||
" # No possible path\n", | ||
" return None\n", | ||
" min_path = float('inf')\n", | ||
" for ta in tangents_A:\n", | ||
" for tb in tangents_B:\n", | ||
" # Compute angles for arc\n", | ||
" angle = angle_between(C, ta, tb)\n", | ||
" # Two possible arcs, choose the smaller one\n", | ||
" arc = min(angle, 2*math.pi - angle) * R\n", | ||
" path = distance(A, ta) + arc + distance(B, tb)\n", | ||
" if path < min_path:\n", | ||
" min_path = path\n", | ||
" return min_path\n", | ||
"\n", | ||
"def main():\n", | ||
" # Read input\n", | ||
" A3D = read_point()\n", | ||
" B3D = read_point()\n", | ||
" C3D = read_point()\n", | ||
" R = int(input())\n", | ||
" # Project to 2D (x and z)\n", | ||
" A = (A3D[0], A3D[2])\n", | ||
" B = (B3D[0], B3D[2])\n", | ||
" C = (C3D[0], C3D[2])\n", | ||
" path_length = compute_path(A, B, C, R)\n", | ||
" if path_length is None:\n", | ||
" print(\"No valid path\")\n", | ||
" else:\n", | ||
" print(\"{0:.2f}\".format(path_length))\n", | ||
"\n", | ||
"if __name__ == \"__main__\":\n", | ||
" main()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "base", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.11.5" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |