首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在qcustomplot中找到交点?

如何在qcustomplot中找到交点?
EN

Stack Overflow用户
提问于 2020-11-18 13:13:02
回答 1查看 107关注 0票数 1

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

EN

回答 1

Stack Overflow用户

发布于 2020-11-18 21:01:28

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

Online demo of the code below

让我们勾勒出一个解决方案。首先,先做一些准备工作,我们检测是否包含了QCustomPlot,以便可以在没有它的情况下测试代码--必要的类是模拟的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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");

一些辅助函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::ostream &operator<<(std::ostream &os, const Point &p) {
    return os << "(" << p.key << ", " << p.value << ")";
}

template <class T> bool has_unique_keys(const T &v) {
    constexpr auto keyEqual = [](const Point &l, const Point &r) { return l.key == r.key; };
    return std::adjacent_find(std::begin(v), std::end(v), keyEqual) == std::end(v);
}

template <class T> bool has_valid_points(const T& v) {
    constexpr auto isValid = [](const Point &p) { return std::isfinite(p.key) && std::isfinite(p.value); };
    return std::all_of(std::begin(v), std::end(v), isValid);
}

线段交点查找器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// intersection of two line segments
std::optional<Point> intersection(const Point &a1, const Point &a2, const Point &b1, const Point &b2)
{
  auto p1 = a1, p2 = a2, p3 = b1, p4 = b2;
  assert(p1.key <= p2.key);
  assert(p3.key <= p4.key);
  if (debugOutput) std::cout << p1 << "-" << p2 << ", " << p3 << "-" << p4;
  auto const denom = (p1.key - p2.key)*(p3.value - p4.value)
                   - (p1.value - p2.value)*(p3.key - p4.key);
  if (fabs(denom) > 1e-6*(p2.key - p1.key)) {
    // the lines are not parallel
    auto const scale = 1.0/denom;
    auto const q = p1.key*p2.value - p1.value*p2.key;
    auto const r = p3.key*p4.value - p3.value*p4.key;
    auto const x = (q*(p3.key-p4.key) - (p1.key-p2.key)*r) * scale;
    if (debugOutput) std::cout << " x=" << x << "\n";
    if (p1.key <= x && x <= p2.key && p3.key <= x && x <= p4.key) {
      auto const y = (q*(p3.value-p4.value) - (p1.value-p2.value)*r) * scale;
      return std::optional<Point>(std::in_place, x, y);
    }
  }
  else if (debugOutput) std::cout << "\n";
  return std::nullopt;
}

一种算法,它遍历按升序key (x)排序的两个点列表,并从这两个列表中找到跨越连续点对的线段的所有交点:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
}

以及一个更通用的版本,它也可以按key升序对点进行排序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
auto findIntersections(Container &d1, Container &d2, bool presorted)
{
  if (!presorted) {
      d1.sort();
      d2.sort();
  }
  return findIntersections(d1, d2);
}

现在来看一些简单的演示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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";
    }
}

演示输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Intersections:
 at (0.785613, 0.706509)
 at (3.92674, -0.706604)
Intersections:
 at (0.785431, 0.706378)
 at (3.92693, -0.706732)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64893815

复制
相关文章
CoordinatorLayout
CoordinatorLayout作为“super-powered FrameLayout”基本实现两个功能:  1、作为顶层布局  2、调度协调子布局 CoordinatorLayout使用新的思路通过协调调度子布局的形式实现触摸影响布局的形式产生动画效果。CoordinatorLayout通过设置子View的 Behaviors来调度子View。系统(Support V7)提供了AppBarLayout.Behavior, AppBarLayout.ScrollingViewBehavior, F
xiangzhihong
2018/02/01
1.4K0
CoordinatorLayout
Android--CoordinatorLayout基本使用
CoordinatorLayout是在desgin包下的一个用于协调子控件的组件,可以解决绝大部分滑动联动问题,使用方法也很简单,为观察者注册一个Behavior,在Behavior指定要监听的控件(
aruba
2020/07/03
1K0
Android--CoordinatorLayout基本使用
滑动吸顶效果
需求是先滑动里面的列表,滑动到一个位置时外面滑动,外面滑动一段距离后再里面滑动。最初想用 CoordinatorLayout 加 RecyclerView,但效果不好直接用,或者用 NestedScrollView 与 RecyclerView 组合使用。
三流之路
2019/05/21
2.7K0
NestedScrollView 嵌套 ListView 实现滑动折叠效果
引言 最近,在做公司一个design折叠效果的时候遇到个问题,就是我们本身app的方法数太多了,dex分包技术还没搞定。不得不尽量缩减一些不必要的包、类。当我们引入RecyclerView的时候,恰好
用户1127566
2018/06/06
3.5K0
CoordinatorLayout与滚动的处理
本博文专门讲解和CoordinatorLayout相关的知识点,这也是Design Support Library中最重要与最难的部分。
小小工匠
2021/08/16
8190
NestedScrolling机制之CoordinatorLayout.Behavior实战
在上一讲中我们讲了NestedScrolling机制,其实android很多有些常用的控件都是支持NestedScrolling机制的,如RecyclerView,NestedScrollView等,
HelloJack
2018/10/11
9070
NestedScrolling机制之CoordinatorLayout.Behavior实战
Floating Action Button-Android M新控件
浮动操作按钮 (简称 FAB) 是: “一个特殊的promoted操作案例。因为一个浮动在UI之上的圆形图标而显得格外突出,同时它还具有特殊的手势行为”
小小工匠
2021/08/16
1.5K0
自定义 Behavior,实现嵌套滑动、平滑切换周月视图的日历
使用 CoordinateLayout 可以协调它的子布局,实现滑动效果的联动,它的滑动效果由 Behavior 实现。以前用过小米日历,对它滑动平滑切换日月视图的效果印象深刻。本文尝试用自定义 Behavior 实现一个带有这种效果的日历。
CCCruch
2019/07/23
3.4K0
自定义 Behavior,实现嵌套滑动、平滑切换周月视图的日历
淘宝首页Bug!嵌套滑动及NestedScroll
学习嵌套滑动的相关文章: 自定义View事件之进阶篇(一)-NestedScrolling(嵌套滑动)机制. Android NestedScrolling机制完全解析 带你玩转嵌套滑动
胡飞洋
2020/07/23
1.5K0
淘宝首页Bug!嵌套滑动及NestedScroll
用 CoordinatorLayout 处理滚动
原文地址:Handling Scrolls with CoordinatorLayout 原文作者:CODEPATH 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m… 译者:Feximin 总览 CoordinatorLayout 扩展了完成 Google's Material Design 中的多种滚动效果的能力。目前,此框架提供了几种不需要写任何自定义动画代码就可以(使动画)工作的方式。这些效果包括: 上下滑动 Floating Action Button 以给 Sn
Android 开发者
2018/05/31
4.9K0
Android之MaterialDesign应用技术
  PS:纵观现在大大小小软件的界面都变的比较漂亮,还有一些系统了,比如小米的MIUI,华为的EMUI等,虽然底层都是安卓,但他们的界面多多少少都会不同,谷歌对这个UI也是非常重视的,MaterialDesign就是今天的主角,首先在看这个的同时,要搞清楚什么是Material Design,百度百科解释,中文名:材料设计语言,是由Google推出的全新的设计语言,谷歌表示,这种设计语言旨在为手机、平板电脑、台式机和“其他平台”提供更一致、更广泛的“外观和感觉”。design,中文是设计之意,即“设想和计划
cMusketeer
2018/03/28
1.3K0
Android之MaterialDesign应用技术
MaterialDesign之FloatingActionButton
就是上面这样了,忘说了一件很重要的事情……FloatingActionButton的监听就是最原始的监听!!!接下来到了重头戏了
蜻蜓队长
2018/08/03
7120
MaterialDesign之FloatingActionButton
自定义 Behavior - 仿新浪微博发现页的实现
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/71732642
程序员徐公
2018/09/17
8820
自定义 Behavior - 仿新浪微博发现页的实现
ViewPager,ScrollView 嵌套ViewPager滑动冲突解决
文章首发地址CSDN:http://blog.csdn.net/gdutxiaoxu/article/details/52939127
全栈程序员站长
2022/09/15
6930
ViewPager,ScrollView 嵌套ViewPager滑动冲突解决
Android studio 最近版安卓pom依赖2020
gridlayout 网格布局 implementation'androidx.gridlayout:gridlayout:1.0.0' drawerlayout 抽屉布局 implementation'androidx.drawerlayout:drawerlayout:1.0.0' NavigationView 侧滑 implementation 'com.google.android.material.navigation.NavigationView:1.0.0' constraintlayout
CaesarChang张旭
2021/01/26
1.4K0
点击加载更多

相似问题

RecyclerView内部的水平RecyclerView CoordinatorLayout内部

32

CoordinatorLayout中的水平RecyclerView

21

带有NestedScrollView和水平滚动RecyclerView的CoordinatorLayout

221

带有NestedScrollView的NestedScrolling,RecyclerView (水平),在CoordinatorLayout内

516

使用RecyclerView的CoordinatorLayout

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文