计算几何学(工程版)

昨天写了计算几何学的东西,今天主要是工程化一下,工程借鉴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

相关推荐
浮生如梦_2 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉4 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer4 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq4 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
wheeldown5 小时前
【数据结构】选择排序
数据结构·算法·排序算法
青花瓷6 小时前
C++__XCode工程中Debug版本库向Release版本库的切换
c++·xcode
观音山保我别报错6 小时前
C语言扫雷小游戏
c语言·开发语言·算法
幺零九零零7 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
TangKenny7 小时前
计算网络信号
java·算法·华为