计算几何学(工程版)

昨天写了计算几何学的东西,今天主要是工程化一下,工程借鉴B站up主

【自动驾驶】自动驾驶planning方向中常用的计算几何学知识 01_哔哩哔哩_bilibili

复制代码
#pragma once

#include <cmath>
#include <iostream>

class Point{
public:
    Point() = default;
    Point(double x_in, double y_in) : x(x_in), y(y_in) {}

    Point operator + (const Point& p) const{
        return {x + p.x, y + p.y};
    }
    Point operator - (const Point& p) const{
        return {x - p.x, y - p.y};
    }
    Point operator*(double k)const {
        return {x * k, y * k};
    }

    friend std::ostream &operator << (std::ostream &out, const Point &p){
        out << "(" << p.x << ", " << p.y << ")";
        return out;
    }

    double DistanceTo(const Point& p) const{
        double dx = x - p.x;
        double dy = y - p.y;
        return std::sqrt(dx * dx + dy * dy);
    }

    double modulus() const{
        return sqrt(x * x + y * y);
    }

    double x;
    double y;
};

class Segment{
public:
    Segment() = default;
    Segment(Point start_in, Point end_in) : start(start_in), end(end_in), direction(end - start) {}

    Segment &operator = (const Segment &s){
        start = s.start;
        end = s.end;
        return *this;
    }
    Segment operator + (const Segment& rhs)const {
        return {start + rhs.start, end + rhs.end};
    }
    Segment operator - (const Segment& rhs)const {
        return {start - rhs.start, end - rhs.end};
    }

    double Length() const{
        return direction.modulus();
    }

    Point unit_direction() const{
        double len = Length();
        if (len != 0) {
            return {direction.x / len, direction.y / len};
        } else {
            // Handle the case where the length is zero (avoid division by zero).
            throw std::runtime_error("Cannot calculate unit direction for a segment with zero length.");
        }
    }

    Point start;
    Point end;
    Point direction;
};

class Line{
public:
    Line() = default;
    Line(Point p1_in, Point p2_in) : p1(p1_in), p2(p2_in), direction(p2_in - p1_in) {}

    Point p1;
    Point p2;
    Point direction;
};

#pragma once

#include "Geometry.h"
#include "utils.h"

double ComputeProjectionLength(const Point& p, const Segment& segement){
    const auto& p1p = p - segement.start;
    return DotProduct(p1p, segement.unit_direction());
}

Point ComputeProjection(const Point& p, const Segment& segment){
    double projection_length = ComputeProjectionLength(p, segment);
    return segment.start + segment.unit_direction() * projection_length;
}

#pragma once

#include "Geometry.h"
#include "utils.h"

// Get distance between point p1 and point p2.
double GetDistance(const Point& p1,  const Point& p2){
    return p1.DistanceTo(p2);
}

// Get distance between point p and a straight line.
double GetDistance(const Point& p, const Line& line){
    Segment p1p2(line.p1, line.p2);
    Segment p1p(line.p1, p);
    return std::abs(CrossProduct(p1p2.direction, p1p.direction)) / p1p2.Length();
}

// Get distance between point p and segment(p1,p2).
double GetDistance(const Point& p, const Segment& segment){
    Segment p1p(segment.start, p);
    Segment p2p(segment.end, p);
    const auto c1 = DotProduct(p1p.direction, segment.direction);
    const auto c2 = DotProduct(p2p.direction, segment.direction);
    if(c1 <= 0){
        //distance(p,segment)=distacne(p1,p).
        return GetDistance(segment.start, p);
    }
    if(c2 >= 0){
        //distance(p,segment)=distacne(p2,p).
        return GetDistance(segment.end, p);
    }
    return std::abs(CrossProduct(segment.direction, p1p.direction)) / segment.Length();
}

#pragma once

#include <iostream>
#include "Geometry.h"

// Calculates dot product.
double DotProduct(const Point& p1, const Point& p2){
    return p1.x * p2.x + p1.y * p2.y;
}

// Calculates cross product.
double CrossProduct(const Point& p1, const Point& p2) {
    return p1.x * p2.y - p2.x * p1.y;
}

#include <iostream>
#include "Geometry.h"
#include "Projection.h"
#include "Distance.h"

int main(){
    Point point(3, 4);
    Segment segment(Point(0.0, 0.0), Point(10.0, 0.0));
    Point projection = ComputeProjection(point, segment);
    std::cout << "projection: " << projection << std::endl;

    Point p1(1, 1);
    Point p2(3, 5);
    std::cout << "Distance between p1 and p2: "
              << GetDistance(p1, p2) << std::endl;

    Line line(Point(0, 0), Point(10, 0));
    Point p(3, 4);
    std::cout << "Distance between p and line: "
              << GetDistance(p, line) << std::endl; 

    Segment seg(Point(5, 5), Point(9, 6));
    std::cout << "Distance between p and segment: "
              << GetDistance(p, seg) << std::endl;
    return 0;
}

TODO

相关推荐
C雨后彩虹4 小时前
任务最优调度
java·数据结构·算法·华为·面试
少林码僧6 小时前
2.31 机器学习神器项目实战:如何在真实项目中应用XGBoost等算法
人工智能·python·算法·机器学习·ai·数据挖掘
钱彬 (Qian Bin)6 小时前
项目实践15—全球证件智能识别系统(切换为Qwen3-VL-8B-Instruct图文多模态大模型)
人工智能·算法·机器学习·多模态·全球证件识别
微露清风6 小时前
系统性学习C++-第十八讲-封装红黑树实现myset与mymap
java·c++·学习
Niuguangshuo6 小时前
EM算法详解:解密“鸡生蛋“的机器学习困局
算法·机器学习·概率论
a3158238067 小时前
Android 大图显示策略优化显示(一)
android·算法·图片加载·大图片
CSARImage7 小时前
C++读取exe程序标准输出
c++
一只小bit7 小时前
Qt 常用控件详解:按钮类 / 显示类 / 输入类属性、信号与实战示例
前端·c++·qt·gui
一条大祥脚7 小时前
26.1.9 轮廓线dp 状压最短路 构造
数据结构·c++·算法
鲨莎分不晴7 小时前
反向传播的数学本质:链式法则与动态规划的完美共舞
算法·动态规划