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