规控常见数学方法-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常见命令......

全部评论
写得好!!!
1 回复 分享
发布于 2024-08-13 18:05 湖南

相关推荐

头像
09-19 19:21
已编辑
门头沟学院 Java
点赞 评论 收藏
分享
感觉初筛都过不去,但是没挂我,我就先等着吧
投递华为技术有限公司等公司10个岗位
点赞 评论 收藏
分享
08-08 11:34
深圳大学 C++
点赞 评论 收藏
分享
08-28 20:36
门头沟学院 Java
点赞 评论 收藏
分享
评论
5
27
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务