Skip to content

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 = c2

2.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(长 + 宽)
正方形4a
梯形0.5(a + b)ha + b + c + d

百炼成钢,融会贯通