计算几何学(工程版)

昨天写了计算几何学的东西,今天主要是工程化一下,工程借鉴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 小时前
第九章-数字三角形
算法
在路上看风景2 小时前
19. 成员初始化列表和初始化对象
c++
uesowys2 小时前
Apache Spark算法开发指导-One-vs-Rest classifier
人工智能·算法·spark
zmzb01032 小时前
C++课后习题训练记录Day98
开发语言·c++
ValhallaCoder2 小时前
hot100-二叉树I
数据结构·python·算法·二叉树
董董灿是个攻城狮2 小时前
AI 视觉连载1:像素
算法
念风零壹3 小时前
C++ 内存避坑指南:如何用移动语义和智能指针解决“深拷贝”与“内存泄漏”
c++
智驱力人工智能3 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
孞㐑¥3 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
月挽清风3 小时前
代码随想录第十五天
数据结构·算法·leetcode