【cpp algorithm】点与线段关系的简单代码

文章介绍了如何使用向量法求解点P在线段AB上的投影长度、投影点坐标、投影点位置、角度值以及判断平行和侧边关系,同时涉及平行四边形面积的计算。
摘要由CSDN通过智能技术生成

写在前面

简单实现

求线段AP在线段AB上的投影长度;
求点P在线段AB上的投影点的坐标;
判断点P的投影点是否在线段AB内;
求∠PAB的角度值;
判断∠PAB是锐角、直角,还是钝角。
求向量AP和AB组成的平行四边形的面积;
若有另外一点Q,判断向量PQ与AB是否平行;
判断点P在向量AB的左侧还是右侧。

方法有三种,向量法可以求的答案多、此外还有面积法和待定系数求解法(设pp的坐标为x,y,直接推导)


#include <iostream>
#include <algorithm>
#include <cmath>
#include <thread>
#include <mutex>
#include <iostream>
#include <glog/logging.h>


using namespace std;

int main (int argc, char* argv[])
{

  google::InitGoogleLogging(argv[0]);
  google::SetStderrLogging(google::GLOG_ERROR); 
  FLAGS_colorlogtostderr = true;



  FLAGS_logtostderr = true; 
  FLAGS_minloglevel = 0;      

  // questions

  float  distance_PtoAB =0;

  pair<int,int> a=make_pair(1,1);
  pair<int,int> b=make_pair(2,4);
  pair<int,int> p=make_pair(3,3);

  pair<int,int> ap=make_pair(2,2);
  pair<int,int> ab=make_pair(1,3);

  pair<int,int> bp=make_pair(1,-1);
  pair<int,int> ba=make_pair(-1,-3);

  float AP_l=sqrt(ap.first*ap.first+ap.second*ap.second);
  float BP_l=sqrt(bp.first*bp.first+bp.second*bp.second);
  float AB_l=sqrt(ab.first*ab.first+ab.second*ab.second);

  float thetaPAB_cos= (ap.first*ab.first+ap.second*ab.second)/AP_l/AB_l;
  float thetaABP_cos= (ba.first*bp.first+ba.second*bp.second)/BP_l/AB_l;
  LOG(INFO) << "thetaPAB_cos: "<< thetaPAB_cos; 
  LOG(INFO) << "thetaABP_cos: "<< thetaABP_cos; 
  cout<<"thetaPAB: "<<acos(thetaPAB_cos)<<endl;
  if (thetaPAB_cos<=0)
  {
    distance_PtoAB=sqrt(ap.first*ap.first+ap.second*ap.second);
    if (thetaPAB_cos!=0)
    {
      cout<<"PAB is obtuse angle"<<endl;
      cout<<"Project of P is outside AB"<<endl;
    }

    
  }
  else if (thetaABP_cos<=0)
  {
    distance_PtoAB=sqrt(bp.first*bp.first+bp.second*bp.second);
    if (thetaABP_cos!=0)
    {
      cout<<"PAB is acute angle"<<endl;
      cout<<"Project of P is outside AB"<<endl;
    }

  }
  else
  {
    distance_PtoAB=(ap.first)*sqrt((1-thetaPAB_cos*thetaPAB_cos));
 
    cout<<"PAB is acute angle"<<endl;
    cout<<"Project of P(PP) is inside AB"<<endl;
       // cal unit vector of AB
    pair <float,float> AB_unitvector (ab.first/AB_l,ab.second/AB_l);
    LOG(INFO) << "AB_unitvector: "<< AB_unitvector.first<<","<<AB_unitvector.second;

    float APP_l=(ap.first*ab.first+ap.second*ab.second)/AB_l;

    pair <float,float> APP (APP_l*AB_unitvector.first,APP_l*AB_unitvector.second);

    pair <float,float> PP (APP.first-a.first,APP.second-a.second);


    cout<<"and the PP is "<< PP.first<<","<<PP.second <<endl;
  }





  std::cout<<"distance_PtoAB: "<<distance_PtoAB<<std::endl;
  google::ShutdownGoogleLogging();

}

sin相关

求向量AP和AB组成的平行四边形的面积;
若有另外一点Q,判断向量PQ与AB是否平行;
判断点P在向量AB的左侧还是右侧。

问题比较简单 通过观察叉乘的结果就可以判断

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个用线段树算区间最值的示例代码,以查询区间最小值为例: ```cpp #include <cstdio> #include <algorithm> using namespace std; const int MAXN = 100005; int n, m; int a[MAXN]; struct Node { int l, r, minn; } tr[MAXN*4]; // 建立线段树 void build(int u, int l, int r) { tr[u].l = l, tr[u].r = r; if (l == r) { // 叶子节 tr[u].minn = a[l]; return; } int mid = (l + r) >> 1; build(u<<1, l, mid); build(u<<1|1, mid+1, r); tr[u].minn = min(tr[u<<1].minn, tr[u<<1|1].minn); } // 查询区间最小值 int query(int u, int ql, int qr) { if (ql <= tr[u].l && tr[u].r <= qr) { // 完全包含 return tr[u].minn; } int mid = (tr[u].l + tr[u].r) >> 1; int res = 0x3f3f3f3f; // 初始化为一个极大值 if (ql <= mid) res = min(res, query(u<<1, ql, qr)); // 左子区间有交集 if (qr > mid) res = min(res, query(u<<1|1, ql, qr)); // 右子区间有交集 return res; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } build(1, 1, n); // 建立线段树 while (m--) { int l, r; scanf("%d%d", &l, &r); printf("%d\n", query(1, l, r)); } return 0; } ``` 这段代码中,建立线段树的过程采用递归方式实现,查询区间最小值的过程也采用递归方式实现。对于每个节,维护该节对应区间的最小值。查询区间最小值的过程,采用线段树的递归查询方式,将查询区间划分成若干个离散的单元,并依次查询每个单元,最终得到查询区间的最小值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值