Appearance
L8_05 代数与平面几何
一、一元一次方程
1.1 一元一次方程定义
一元一次方程的一般形式:ax + b = 0
1.2 解方程
cpp
// 求解 ax + b = 0
double solveLinearEquation(double a, double b) {
if (a == 0) {
// 无解或无穷多解
if (b == 0) {
// 无穷多解
return 0; // 特殊标记
} else {
// 无解
return NAN;
}
}
return -b / a;
}1.3 应用:求直线交点
cpp
// 两条直线的交点
// 直线1: a1*x + b1*y = c1
// 直线2: a2*x + b2*y = c2
pair<double, double> lineIntersection(double a1, double b1, double c1,
double a2, double b2, double c2) {
double det = a1 * b2 - a2 * b1;
if (det == 0) {
// 平行或重合
return {NAN, NAN};
}
double x = (b2 * c1 - b1 * c2) / det;
double y = (a1 * c2 - a2 * c1) / det;
return {x, y};
}二、二元一次方程组
2.1 二元一次方程组定义
cpp
// 方程组:
// a1*x + b1*y = c1
// a2*x + b2*y = c22.2 高斯消元法求解
cpp
// 求解二元一次方程组
bool solveLinearSystem(double a1, double b1, double c1,
double a2, double b2, double c2,
double& x, double& y) {
double det = a1 * b2 - a2 * b1;
if (det == 0) {
// 无解或无穷多解
return false;
}
x = (b2 * c1 - b1 * c2) / det;
y = (a1 * c2 - a2 * c1) / det;
return true;
}2.3 矩阵形式求解
cpp
// 使用矩阵求逆求解
bool solveLinearSystemMatrix(double a1, double b1, double c1,
double a2, double b2, double c2,
double& x, double& y) {
double det = a1 * b2 - a2 * b1;
if (det == 0) return false;
// 逆矩阵
double inv_a = b2 / det;
double inv_b = -b1 / det;
double inv_c = -a2 / det;
double inv_d = a1 / det;
x = inv_a * c1 + inv_b * c2;
y = inv_c * c1 + inv_d * c2;
return true;
}三、三角形面积
3.1 底乘高公式
cpp
double triangleAreaBaseHeight(double base, double height) {
return 0.5 * base * height;
}3.2 海伦公式
cpp
double triangleAreaHeron(double a, double b, double c) {
double s = (a + b + c) / 2;
return sqrt(s * (s - a) * (s - b) * (s - c));
}3.3 向量叉积公式
cpp
struct Point {
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
};
double triangleAreaCross(const Point& a, const Point& b, const Point& c) {
double cross = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
return fabs(cross) / 2;
}3.4 鞋带公式(多边形面积)
cpp
double polygonArea(const vector<Point>& points) {
double area = 0;
int n = points.size();
for (int i = 0; i < n; i++) {
int j = (i + 1) % n;
area += points[i].x * points[j].y;
area -= points[j].x * points[i].y;
}
return fabs(area) / 2;
}四、圆形面积
4.1 基本公式
cpp
double circleArea(double radius) {
return M_PI * radius * radius;
}4.2 圆环面积
cpp
double annulusArea(double outerRadius, double innerRadius) {
return M_PI * (outerRadius * outerRadius - innerRadius * innerRadius);
}4.3 扇形面积
cpp
// angle: 圆心角(弧度)
double sectorArea(double radius, double angle) {
return 0.5 * radius * radius * angle;
}4.4 圆弧长度
cpp
double arcLength(double radius, double angle) {
return radius * angle;
}五、长方形面积
5.1 基本公式
cpp
double rectangleArea(double width, double height) {
return width * height;
}5.2 矩形周长
cpp
double rectanglePerimeter(double width, double height) {
return 2 * (width + height);
}5.3 正方形对角线
cpp
double squareDiagonal(double side) {
return side * sqrt(2);
}六、几何计算综合应用
6.1 点到直线的距离
cpp
// 直线: ax + by + c = 0
double pointToLineDistance(double x, double y, double a, double b, double c) {
return fabs(a * x + b * y + c) / sqrt(a * a + b * b);
}6.2 点到线段的距离
cpp
double pointToSegmentDistance(const Point& p, const Point& a, const Point& b) {
double dx = b.x - a.x;
double dy = b.y - a.y;
double t = ((p.x - a.x) * dx + (p.y - a.y) * dy) / (dx * dx + dy * dy);
t = max(0.0, min(1.0, t));
double nearestX = a.x + t * dx;
double nearestY = a.y + t * dy;
double distX = p.x - nearestX;
double distY = p.y - nearestY;
return sqrt(distX * distX + distY * distY);
}6.3 判断点是否在多边形内(射线法)
cpp
bool pointInPolygon(const Point& p, const vector<Point>& polygon) {
int n = polygon.size();
bool inside = false;
for (int i = 0, j = n - 1; i < n; j = i++) {
Point pi = polygon[i];
Point pj = polygon[j];
if (((pi.y > p.y) != (pj.y > p.y)) &&
(p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x)) {
inside = !inside;
}
}
return inside;
}6.4 判断两条线段是否相交
cpp
int orientation(const Point& p, const Point& q, const Point& r) {
double val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
if (val == 0) return 0; // 共线
return (val > 0) ? 1 : 2; // 顺时针或逆时针
}
bool segmentsIntersect(const Point& a1, const Point& a2, const Point& b1, const Point& b2) {
int o1 = orientation(a1, a2, b1);
int o2 = orientation(a1, a2, b2);
int o3 = orientation(b1, b2, a1);
int o4 = orientation(b1, b2, a2);
// 一般情况
if (o1 != o2 && o3 != o4) return true;
// 特殊情况(共线)
// 检查点是否在线段上
auto onSegment = [](const Point& p, const Point& q, const Point& r) {
return q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y);
};
if (o1 == 0 && onSegment(a1, b1, a2)) return true;
if (o2 == 0 && onSegment(a1, b2, a2)) return true;
if (o3 == 0 && onSegment(b1, a1, b2)) return true;
if (o4 == 0 && onSegment(b1, a2, b2)) return true;
return false;
}6.5 凸包(Graham扫描法)
cpp
Point pivot;
double distanceSquared(const Point& a, const Point& b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return dx * dx + dy * dy;
}
int compare(const Point& a, const Point& b) {
int o = orientation(pivot, a, b);
if (o != 0) return o == 2 ? -1 : 1;
return distanceSquared(pivot, a) < distanceSquared(pivot, b) ? -1 : 1;
}
vector<Point> convexHull(vector<Point> points) {
int n = points.size();
if (n <= 1) return points;
// 找到最左下角的点
int minIdx = 0;
for (int i = 1; i < n; i++) {
if (points[i].y < points[minIdx].y ||
(points[i].y == points[minIdx].y && points[i].x < points[minIdx].x)) {
minIdx = i;
}
}
swap(points[0], points[minIdx]);
pivot = points[0];
sort(points.begin() + 1, points.end(), compare);
vector<Point> hull;
hull.push_back(points[0]);
hull.push_back(points[1]);
for (int i = 2; i < n; i++) {
while (hull.size() >= 2 && orientation(hull[hull.size() - 2], hull.back(), points[i]) != 2) {
hull.pop_back();
}
hull.push_back(points[i]);
}
return hull;
}七、几何公式总结
| 图形 | 面积公式 | 周长/长度公式 |
|---|---|---|
| 三角形 | 0.5 × 底 × 高 | a + b + c |
| 圆形 | πr² | 2πr |
| 扇形 | 0.5r²θ | rθ + 2r |
| 矩形 | 长 × 宽 | 2(长 + 宽) |
| 正方形 | a² | 4a |
| 梯形 | 0.5(a + b)h | a + b + c + d |
