Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在qcustomplot中找到交点?_C++_Qt_Qcustomplot - Fatal编程技术网

C++ 如何在qcustomplot中找到交点?

C++ 如何在qcustomplot中找到交点?,c++,qt,qcustomplot,C++,Qt,Qcustomplot,我有一个基于qt(qcustomplot)的应用程序,它可以打印两个不同的图形。它们有一个交点。如何找到该点的x和y坐标?这与绘图没有多大关系,因为您将调查基础数据。假设我们可以使用直线在数据点之间插值,并且数据集是单值的(即,对于任何x或key坐标,只有一个值) 让我们草拟一个解决方案。首先是一些预备知识,我们检测是否包含QCustomPlot,以便在没有它的情况下测试代码-模拟必要的类: #define _USE_MATH_DEFINES #include <algorithm>

我有一个基于qt(qcustomplot)的应用程序,它可以打印两个不同的图形。它们有一个交点。如何找到该点的x和y坐标?

这与绘图没有多大关系,因为您将调查基础数据。假设我们可以使用直线在数据点之间插值,并且数据集是单值的(即,对于任何
x
key
坐标,只有一个值)

让我们草拟一个解决方案。首先是一些预备知识,我们检测是否包含QCustomPlot,以便在没有它的情况下测试代码-模拟必要的类:

#define _USE_MATH_DEFINES
#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <optional>
#include <type_traits>
#include <vector>
//#include "qcustomplot.h"

constexpr bool debugOutput = false;

#ifndef QCP_PLOTTABLE_GRAPH_H
struct QCPGraphData { 
  double key, value;
  QCPGraphData() = default;
  QCPGraphData(double x, double y) : key(x), value(y) {}
};
#endif

auto keyLess(const QCPGraphData &l, const QCPGraphData &r) { return l.key < r.key; }

#ifndef QCP_PLOTTABLE_GRAPH_H
template <typename T> struct QCPDataContainer : public std::vector<T> {
  using std::vector<T>::vector;
  void sort() { std::sort(this->begin(), this->end(), keyLess); }
};
using QCPGraphDataContainer = QCPDataContainer<QCPGraphData>;
#endif

using Point = QCPGraphData;
using Container = QCPGraphDataContainer;
static_assert(std::is_copy_constructible_v<Point>, "Point must be copy-constructible");
还有一个更通用的版本,它还可以按升序
顺序对点进行排序:

auto findIntersections(Container &d1, Container &d2, bool presorted)
{
  if (!presorted) {
      d1.sort();
      d2.sort();
  }
  return findIntersections(d1, d2);
}
下面是一些简单的演示:

template <typename Fun>
Container makeGraph(double start, double step, double end, Fun &&fun) {
    Container result;
    int i = 0;
    for (auto x = start; x <= end; x = ++i * step)
        result.emplace_back(x, fun(x));
    return result;
}

int main()
{
    for (auto step2: {0.1, 0.1151484584}) {
        auto sinPlot = makeGraph(-2*M_PI, 0.1, 3*M_PI, sin);
        auto cosPlot = makeGraph(0., step2, 2*M_PI, cos);
        auto intersections = findIntersections(sinPlot, cosPlot);
        std::cout << "Intersections:\n";
        for (auto &ip : intersections)
            std::cout << " at " << ip << "\n";
    }
}

谢谢你的解释,我想如果你有直线上两点的坐标,你可以很容易地找到它的方程。假设你有一条线AB,你知道a(x1,y1),B(x2,y2)),然后你只需要做一个方程(y-y1)/(y2-y1)=(x-x1)/(x2-x1),你可以用这个方程来表示y。有了第二条直线的方程式,你们就能找到它们的交点的x和y坐标(若它们不匹配也不平行的话)。
std::vector<Point> findIntersections(const Container &a_, const Container &b_)
{
  if (a_.size() < 2 || b_.size() < 2) return {};
  static constexpr auto check = [](const auto &c){
      assert(has_valid_points(c));
      assert(std::is_sorted(c.begin(), c.end(), keyLess));
      assert(has_unique_keys(c));
  };
  check(a_);
  check(b_);
  bool aFirst = a_.front().key <= b_.front().key;
  const auto &a = aFirst ? a_ : b_, &b = aFirst ? b_ : a_;
  assert(a.front().key <= b.front().key);
  if (a.back().key < b.front().key) return {}; // the key spans don't overlap

  std::vector<Point> intersections;
  auto ia = a.begin(), ib = b.begin();
  Point a1 = *ia++, b1 = *ib++;
  while (ia->key < b1.key) a1=*ia++; // advance a until the key spans overlap
  for (Point a2 = *ia, b2 = *ib;;) {
    auto const ipt = intersection(a1, a2, b1, b2);
    if (ipt)
      intersections.push_back(*ipt);
    bool advanceA = a2.key <= b2.key, advanceB = b2.key <= a2.key;
    if (advanceA) {
      if (++ia == a.end()) break;
      a1 = a2, a2 = *ia;
    }
    if (advanceB) {
      if (++ib == b.end()) break;
      b1 = b2, b2 = *ib;
    }
  }
  return intersections;
}
auto findIntersections(Container &d1, Container &d2, bool presorted)
{
  if (!presorted) {
      d1.sort();
      d2.sort();
  }
  return findIntersections(d1, d2);
}
template <typename Fun>
Container makeGraph(double start, double step, double end, Fun &&fun) {
    Container result;
    int i = 0;
    for (auto x = start; x <= end; x = ++i * step)
        result.emplace_back(x, fun(x));
    return result;
}

int main()
{
    for (auto step2: {0.1, 0.1151484584}) {
        auto sinPlot = makeGraph(-2*M_PI, 0.1, 3*M_PI, sin);
        auto cosPlot = makeGraph(0., step2, 2*M_PI, cos);
        auto intersections = findIntersections(sinPlot, cosPlot);
        std::cout << "Intersections:\n";
        for (auto &ip : intersections)
            std::cout << " at " << ip << "\n";
    }
}
Intersections:
 at (0.785613, 0.706509)
 at (3.92674, -0.706604)
Intersections:
 at (0.785431, 0.706378)
 at (3.92693, -0.706732)