引言
在上一篇文章中,我们介绍了项目的基本情况和使用方法。本文我们将深入探讨核心几何工具类的设计原理、实现细节和使用技巧。
设计理念
我们的几何工具类设计遵循以下原则:
- 面向对象设计:每个几何图形都是一个类,封装了相关的属性和方法
- 易于使用:提供直观的API,隐藏复杂的计算细节
- 功能完整:覆盖初中几何的主要计算需求
- 可扩展性:模块化设计,易于添加新功能
Point类 - 几何的基础
设计思路
点是几何中最基本的元素,所有其他几何图形都由点构成。Point类封装了点的坐标和基本操作。
核心实现
python
class Point:
def __init__(self, x: float, y: float, label: str = ''):
self.x = x
self.y = y
self.label = label
主要方法
1. 距离计算
计算两点之间的欧几里得距离:
python
def distance_to(self, other: 'Point') -> float:
return math.sqrt((self.x - other.x)**2 + (self.y - other.y)**2)
使用示例:
python
A = Point(0, 0, 'A')
B = Point(3, 4, 'B')
distance = A.distance_to(B) # 结果: 5.0
这验证了勾股定理:3² + 4² = 5²。
2. 中点计算
计算两点的中点:
python
def midpoint(self, other: 'Point') -> 'Point':
return Point((self.x + other.x) / 2, (self.y + other.y) / 2)
应用场景:
- 计算线段的中点
- 绘制三角形的中线
- 四边形的对角线交点
3. 点的平移
python
def translate(self, dx: float, dy: float) -> 'Point':
return Point(self.x + dx, self.y + dy, self.label)
使用示例:
python
# 创建一个点
A = Point(2, 3, 'A')
# 向右平移3个单位,向上平移2个单位
A_translated = A.translate(3, 2) # 结果: Point(5, 5, 'A')
Line类 - 直线的表示与计算
设计思路
直线由两个点确定。我们使用两点式表示直线,并提供多种计算方法。
核心实现
python
class Line:
def __init__(self, p1: Point, p2: Point, label: str = ''):
self.p1 = p1
self.p2 = p2
self.label = label
主要方法
1. 斜率计算
python
def slope(self) -> Optional[float]:
dx = self.p2.x - self.p1.x
if abs(dx) < 1e-10:
return None # 垂直线
return (self.p2.y - self.p1.y) / dx
注意事项:
- 垂直线没有斜率(返回None)
- 水平线的斜率为0
- 使用容差(1e-10)处理浮点数误差
2. 直线方程
将直线转换为一般式方程 ax + by + c = 0:
python
def equation(self) -> Tuple[float, float, float]:
a = self.p2.y - self.p1.y
b = self.p1.x - self.p2.x
c = self.p2.x * self.p1.y - self.p1.x * self.p2.y
return (a, b, c)
应用场景:
- 计算两条直线的交点
- 计算点到直线的距离
- 判断点是否在直线上
3. 平行和垂直判断
python
def is_parallel_to(self, other: 'Line') -> bool:
s1 = self.slope()
s2 = other.slope()
if s1 is None and s2 is None:
return True # 都是垂直线
if s1 is None or s2 is None:
return False
return abs(s1 - s2) < 1e-10
def is_perpendicular_to(self, other: 'Line') -> bool:
s1 = self.slope()
s2 = other.slope()
if s1 is None:
return s2 == 0 # 一条垂直,一条水平
if s2 is None:
return s1 == 0
return abs(s1 * s2 + 1) < 1e-10
数学原理:
- 两条直线平行 ⟺ 斜率相等(或都是垂直线)
- 两条直线垂直 ⟺ 斜率乘积为-1
4. 交点计算
计算两条直线的交点:
python
def intersection(self, other: 'Line') -> Optional[Point]:
a1, b1, c1 = self.equation()
a2, b2, c2 = other.equation()
denominator = a1 * b2 - a2 * b1
if abs(denominator) < 1e-10:
return None # 平行或重合
x = (b1 * c2 - b2 * c1) / denominator
y = (a2 * c1 - a1 * c2) / denominator
return Point(x, y)
应用示例:
python
# 创建两条直线
line1 = Line(Point(0, 0), Point(2, 2))
line2 = Line(Point(0, 2), Point(2, 0))
# 计算交点
intersection = line1.intersection(line2)
print(intersection) # Point(1.0, 1.0)
5. 点到直线的距离
python
def distance_to_point(self, point: Point) -> float:
a, b, c = self.equation()
return abs(a * point.x + b * point.y + c) / math.sqrt(a**2 + b**2)
公式推导 :
点到直线 ax + by + c = 0 的距离为:
d=∣ax0+by0+c∣a2+b2d = \frac{|ax_0 + by_0 + c|}{\sqrt{a^2 + b^2}}d=a2+b2 ∣ax0+by0+c∣
6. 垂直平分线
python
def perpendicular_bisector(self) -> 'Line':
mid = self.p1.midpoint(self.p2)
dx = self.p2.x - self.p1.x
dy = self.p2.y - self.p1.y
p2 = Point(mid.x - dy, mid.y + dx)
return Line(mid, p2)
应用场景:
- 三角形的外心(三条垂直平分线的交点)
- 圆的弦的垂直平分线
Circle类 - 圆的计算
设计思路
圆由圆心和半径确定。我们提供了圆的各种计算功能。
核心实现
python
class Circle:
def __init__(self, center: Point, radius: float, label: str = ''):
self.center = center
self.radius = radius
self.label = label
主要方法
1. 面积和周长
python
def area(self) -> float:
return math.pi * self.radius ** 2
def circumference(self) -> float:
return 2 * math.pi * self.radius
2. 圆上的点
根据角度获取圆上的点:
python
def point_on_circle(self, angle: float) -> Point:
x = self.center.x + self.radius * math.cos(angle)
y = self.center.y + self.radius * math.sin(angle)
return Point(x, y)
使用示例:
python
circle = Circle(Point(0, 0), 3)
# 获取0度(右侧)的点
p1 = circle.point_on_circle(0) # Point(3.0, 0.0)
# 获取90度(上方)的点
p2 = circle.point_on_circle(math.pi / 2) # Point(0.0, 3.0)
3. 弦长和弧长
python
def chord_length(self, angle: float) -> float:
return 2 * self.radius * math.sin(angle / 2)
def arc_length(self, angle: float) -> float:
return self.radius * angle
数学原理:
- 弦长公式:c=2rsin(θ/2)c = 2r\sin(\theta/2)c=2rsin(θ/2)
- 弧长公式:l=rθl = r\thetal=rθ(θ\thetaθ为弧度)
4. 扇形面积
python
def sector_area(self, angle: float) -> float:
return 0.5 * self.radius ** 2 * angle
5. 切线计算
计算圆上某点的切线:
python
def tangent_at_point(self, point: Point) -> Optional['Line']:
if not self.contains_point(point):
return None
dx = point.x - self.center.x
dy = point.y - self.center.y
# 切线方向垂直于半径
p2 = Point(point.x - dy, point.y + dx)
return Line(point, p2)
数学原理 :
切线与半径垂直,所以切线的方向向量是半径方向向量的垂直向量。
Triangle类 - 三角形的完整功能
设计思路
三角形是几何中的重要图形,我们提供了丰富的计算方法。
核心实现
python
class Triangle:
def __init__(self, p1: Point, p2: Point, p3: Point, label: str = ''):
self.p1 = p1
self.p2 = p2
self.p3 = p3
self.label = label
主要方法
1. 面积计算(海伦公式)
python
def area(self) -> float:
a, b, c = self.side_lengths()
s = (a + b + c) / 2 # 半周长
return math.sqrt(s * (s - a) * (s - b) * (s - c))
海伦公式 :
S=s(s−a)(s−b)(s−c)S = \sqrt{s(s-a)(s-b)(s-c)}S=s(s−a)(s−b)(s−c)
其中 s=a+b+c2s = \frac{a+b+c}{2}s=2a+b+c 是半周长。
2. 内角计算(余弦定理)
python
def angles(self) -> Tuple[float, float, float]:
a, b, c = self.side_lengths()
angle1 = math.acos(max(-1, min(1, (b**2 + c**2 - a**2) / (2 * b * c))))
angle2 = math.acos(max(-1, min(1, (a**2 + c**2 - b**2) / (2 * a * c))))
angle3 = math.acos(max(-1, min(1, (a**2 + b**2 - c**2) / (2 * a * b))))
return (angle1, angle2, angle3)
余弦定理 :
cosA=b2+c2−a22bc\cos A = \frac{b^2 + c^2 - a^2}{2bc}cosA=2bcb2+c2−a2
3. 特殊点计算
重心(Centroid):
python
def centroid(self) -> Point:
x = (self.p1.x + self.p2.x + self.p3.x) / 3
y = (self.p1.y + self.p2.y + self.p3.y) / 3
return Point(x, y, "G")
重心是三条中线的交点,坐标是三个顶点坐标的平均值。
外心(Circumcenter):
python
def circumcenter(self) -> Point:
line1 = Line(self.p1, self.p2).perpendicular_bisector()
line2 = Line(self.p2, self.p3).perpendicular_bisector()
return line1.intersection(line2)
外心是三条垂直平分线的交点。
内心(Incenter):
python
def incenter(self) -> Point:
a, b, c = self.side_lengths()
perimeter = a + b + c
x = (a * self.p1.x + b * self.p2.x + c * self.p3.x) / perimeter
y = (a * self.p1.y + b * self.p2.y + c * self.p3.y) / perimeter
return Point(x, y, "I")
内心是三条角平分线的交点,坐标是顶点坐标的加权平均,权重是对边长。
垂心(Orthocenter):
python
def orthocenter(self) -> Point:
line1 = self._altitude(self.p1)
line2 = self._altitude(self.p2)
return line1.intersection(line2)
垂心是三条高线的交点。
4. 高、中线、角平分线
这些方法在三角形类中都有实现,用于绘制和计算。
GeometryVisualizer类 - 可视化工具
设计思路
可视化器封装了matplotlib的复杂操作,提供简单易用的API。
核心功能
1. 初始化
python
def __init__(self, figsize: Tuple[int, int] = (10, 8), dpi: int = 100):
self.fig, self.ax = plt.subplots(figsize=figsize, dpi=dpi)
self.ax.set_aspect('equal') # 保持纵横比
self.ax.grid(True, alpha=0.3) # 显示网格
2. 绘制方法
所有绘制方法都支持颜色、大小、透明度等参数,使用简单直观。
3. 自动调整坐标轴
python
def auto_limits(self, points: List[Point], margin: float = 1.0):
x_coords = [p.x for p in points]
y_coords = [p.y for p in points]
x_min, x_max = min(x_coords), max(x_coords)
y_min, y_max = min(y_coords), max(y_coords)
self.ax.set_xlim(x_min - margin, x_max + margin)
self.ax.set_ylim(y_min - margin, y_max + margin)
使用技巧
1. 组合使用多个类
python
# 创建三角形
triangle = Triangle(Point(0, 0), Point(3, 0), Point(1.5, 2))
# 计算外心
circumcenter = triangle.circumcenter()
# 计算外接圆半径
radius = circumcenter.distance_to(triangle.p1)
# 创建外接圆
circumcircle = Circle(circumcenter, radius)
# 可视化
viz = GeometryVisualizer()
viz.plot_triangle(triangle)
viz.plot_circle(circumcircle, fill=False)
viz.show()
2. 处理浮点数误差
在几何计算中,浮点数误差是常见问题。我们使用容差(如1e-10)来处理:
python
# 判断两条直线是否平行
if abs(slope1 - slope2) < 1e-10:
print("两条直线平行")
3. 性能优化
对于大量点的计算,可以考虑使用numpy数组来提高性能。
总结
本文详细介绍了核心几何工具类的设计原理和实现细节:
- Point类:几何的基础,提供距离、中点等基本操作
- Line类:直线的表示和计算,包括斜率、交点、距离等
- Circle类:圆的计算,包括面积、周长、弦长、弧长等
- Triangle类:三角形的完整功能,包括面积、内角、特殊点等
- GeometryVisualizer类:可视化工具,简化图形绘制
这些工具类为后续的示例应用提供了坚实的基础。在下一篇文章中,我们将介绍如何使用这些工具来解决具体的三角形问题。