规控常见数学方法-C++
一、求方程的根
牛顿法
1、求数字的算术平方根
// 牛顿法求 num 的平方根
// 令f(x) = x^2 - num , 求 f(x) 的零点
// initial_num (x0) last_num: x(1)
#include<iostream>
using namespace std;
#include<cmath>
double getroot(const double & num){
if(num==0||num==1)return num;
double error = 1e-17;
double initial_num = num/2.0;
double last_num = (num/initial_num+initial_num)/2.0;
while ( fabs(last_num - initial_num) > error)
{
initial_num = last_num;
last_num = (num/initial_num+initial_num)/2.0;
}
return last_num;
}
int main(){
double enter_num;
cin>>enter_num;
cout<< "the root is :"<<getroot(enter_num)<<endl;
return 0;
}
2、求x 2 − ln x = 0的根
原文链接:https://blog.csdn.net/weixin_42301220/article/details/126816206
#include<iostream>
using namespace std;
constexpr double esp = 1e-6;
int main() {
double initial_num = 2;
double last_num = initial_num - (initial_num * initial_num + log(initial_num)) / (2.0 * initial_num + (1 / initial_num));
while (abs(initial_num-last_num)>=esp)
{
initial_num = last_num;
last_num = initial_num - (initial_num * initial_num + log(initial_num)) / (2.0 * initial_num + (1 / initial_num));
}
cout << last_num << endl;
return 0;
}
二、计算几何学
Geometry
Point:
class Point {
public:
Point() = default;
Point(double x_in, double y_in) :x(x_in), y(y_in) {}; //拷贝构造函数
Point(const Point& p) :x(p.x), y(p.y) {};
Point& operator=(const Point& p) { //赋值运算符
x = p.x;
y = p.y;
return *this;
}
Point operator+(const Point& p) {
return { x + p.x, y + p.y };
}
Point operator-(const Point& p) const {
return { x - p.x, y - p.y };
}
double operator*(const Point& p) const {
return x * p.x + y * p.y;
}
Point operator*(double k)const {
return { x * k, y * k };
}
friend Point operator*(double k, const Point& p) {
return { p.x * k, p.y * k };
}
bool operator==(const Point& p)const {
return p.x == x && p.y == y;
}
bool operator!=(const Point& p)const {
return !(p.x == x && p.y == y);
}
double modulus()const {
return sqrt(x * x + y * y);
}
double DistanceTo(const Point& other)const {
double dx = x - other.x;
double dy = y - other.y;
return sqrt(dx * dx + dy * dy);
}
friend std::ostream& operator<<(std::ostream& out, const Point& p) {
out << "(" << p.x << ", " << p.y << ")";
return out;
}
public:
double x;
double y;
};
直线line:
//Define line segment.
class Line {
public:
Line() = default;
Line(Point p1_in, Point p2_in) : p1(p1_in), p2(p2_in), direction(p2_in - p1_in) {
};
friend std::ostream& operator<<(std::ostream& out, const Line& line) {
out << "Line: " << line.p1 << " ---> " << line.p2;
return out;
}
public:
Point p1;
Point p2;
Point direction;
};
线段segment:
class Segment {
public:
Segment() = default;
Segment(Point start_in, Point end_in) : start(start_in), end(end_in), direction(end - start) {
}
Segment(const Segment& s) : start(s.start), end(s.end), 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 {
int len = length();
if (len != 0) {
return { len / direction.x , len / direction.y };
}
else throw std::runtime_error("Cannot calculate unit direction for a segment with zero length.");
}
friend std::ostream& operator<<(std::ostream& out, const Segment& s) {
out << "Segment: " << s.start << " ---> " << s.end;
return out;
}
public:
Point start;
Point end;
Point direction;
};
折线段polyline:
class Polyline {
Polyline() = default;
Polyline(const std::vector<Point>& pts) :points(pts) {
for (int i = 1; i < points.size(); ++i) {
segs.push_back(Segment(points[i - 1], points[i]));
}
}
Polyline(const std::vector<Segment>& segs_) : segs(segs_) {
for (int i = 0; i < segs.size(); ++i) {
points.push_back(segs[i].start);
}
points.push_back(segs[segs.size() - 1].end);
}
void append(const Segment& seg) {
if (!segs.empty() && segs.back().end != seg.start) {
throw std::invalid_argument("Disconnected Segment");
}
segs.push_back(seg);
points.push_back(seg.end);
}
void append(const Point& p) {
const auto seg = Segment(points.back(), p);
points.push_back(p);
segs.push_back(seg);
}
Polyline operator+(const Polyline& other) const {
Polyline result;
result.segs = this->segs;
result.points = this->points;
for (auto& seg : other.segs) {
result.append(seg);
}
return result;
}
Segment GetSegmentByIndex(int index) {
if (index < 0 || index >= segs.size()) {
throw std::out_of_range("Index out of range");
}
return segs[index];
}
std::vector<Point> Points() const {
return points;
}
std::vector<Segment> Segments()const {
return segs;
}
private:
vector<Point> points;
vector<Segment> segs;
};
Algorithm
基本运算
点积:
constexpr double Epsilon = 1e-6;
using Vec = Point; //类型别名
// 点积运算
double DotProduct(const Vec& v1, const Vec& v2) {
return v1.x * v2.x + v1.y + v2.y;
}
叉乘:
// 叉乘运算
double CrossProduct(const Vec& v1, const Vec& v2) {
return v1.x * v2.y - v2.x * v1.y;
}
int Sign(double x) {
return x < 0 ? -1 : x>0 ? 1 : 0;
}
Projection
点到线段的距离:
// 计算点到线段的投影长度 x (p1p*cos(theta))
double ComputeProjectionLength(const Point& p, const Segment& seg) {
const auto& p1p = p - seg.start;
return DotProduct(p1p, seg.unit_direction());
}
点到线段的投影点:
// Compute projection point of point p.
Point ComputeProjection(const Point& p, const Segment& segment) {
double projection_length = ComputeProjectionLength(p, segment);
Point ans;
ans.x = segment.start.x + segment.unit_direction().x * projection_length;
ans.y = segment.start.y + segment.unit_direction().y * projection_length;
return ans;
}
Distance-求距离
point to point:
// Get distance between point p1 and point p2.
double GetDistance(const Point& p1, const Point& p2) {
return p1.DistanceTo(p2);
}
point to line:
// 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);
/*p1p_.x = p1p.end.x - p1p.start.x;
p1p_.y = p1p.end.y - p1p.start.y;*/
return abs(CrossProduct(p1p.direction, p1p2.unit_direction()));
}
point to segment:

// Get distance between point p and segment(p1,p2).
double GetDistance(const Point& p, const Segment& seg) {
Segment p1p(seg.start, p);
Segment p2p(seg.end, p);
const auto c1 = DotProduct(p1p.direction,seg.direction);
const auto c2 = DotProduct(p2p.direction,seg.direction);
if (c1 <= 0)return GetDistance(p, seg.start);
if (c2 >= 0)return GetDistance(p, seg.end);
return abs(CrossProduct(p1p.direction, seg.unit_direction()));// 投影点在线段上
}
segment to segment:
四个端点到线段的最小值
double GetDistance(const Segment& seg1, const Segment& seg2) {
const double d1 = GetDistance(seg1.start, seg2);
const double d2 = GetDistance(seg1.end, seg2);
const double d3 = GetDistance(seg2.start, seg1);
const double d4 = GetDistance(seg1.end, seg1);
return min(min(d1, d2), min(d3, d4));
}
Side-求相对位置关系
enum class Side {
// When the segment's length is zero, it's useless to determine the side, so we use DEFAULT_NO_SIDE to show.
DEFAULT_NO_SIDE = 0,
LEFT,
RIGHT,
// The three below states mean that the point is in line.
ON_AFTER,
ON_BEFORE,
WITHIN
};
也就是说点与线段的相对位置关系包括以下5种:
- 点在线段的左边
- 点在线段的右边
- 点在线段所在的直线上点在线段前面点在线段后面点在线段内部
判断点跟一条线段的相对位置关系:

//判断点和线段的位置关系(5种)
// Determine which side of the segment the point is.
Side GetSide(const Point& p, const Segment& s) {
const auto& p0 = s.start;
const auto& p2 = s.end;
const auto& a = p - p0;
const auto& b = p2 - p0;
const auto cross_product = CrossProduct(a, b);
if (cross_product != 0) {
// Returns LEFT if p0,p,p2 are clockwise position, returns RIGHT means p0,p,p2 are counter-clockwise position.
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
自动驾驶/机器人C++八股精选 文章被收录于专栏
在自动驾驶和机器人领域,C++因其高性能、内存管理高效和跨平台兼容性等特性,被广泛应用。本专栏整理了C++面试中常遇到的八股问题,可私信作者要飞书文档,不论是嵌入式软开、算法、软件开发都可以阅读,包括了C++的虚函数、C++11新特性、C++的STL库、Linux常见命令......
传音控股公司福利 327人发布