用于数据可视化的 Catmull-Rom 样条线

问题描述 投票:0回答:1

所以我正在做一个项目,我们使用凸包对点进行分组,并使用 Catmull-Rom 样条线使其更圆,如图所示:

Visual representation

现在我的下一个任务是将可以看到的路径连接到凸包,这样我看起来像这样:

This is done using bubblesets

所以我不知道如何解决这个问题,我想创建像bubblests中那样连接圆圈的路径,这些弯曲的路径,但我不确定我应该看什么数学,我想自己做一个不仅仅是使用实现它的库,我还查看了以下内容:\

https://github.com/MultiSetVis/MultiSetVis.github.io - 特别是简单的散点图示例。 https://bubblesets-js.josuakrause.com/
但我仍然不确定他们是如何做到这一点的,所以如果有人有任何想法,我会洗耳恭听。

javascript bezier convex-hull catmull-rom-curve
1个回答
0
投票

您发布的第二个链接实际上是一个 JavaScript 库(使用

npm i bubblesets
安装)。

然后,你可以得到这样的轮廓:

import {
  BSplineShapeGenerator,
  BubbleSet,
  PointPath,
  ShapeSimplifier,
} from 'bubblesets';

const pad = 3;
const bubbles = new BubbleSet();
const rectanglesToInclude = [
  { x: 30, y: 40, width: 10, height: 20 },
  { x: 60, y: 30, width: 20, height: 10 },
  { x: 50, y: 50, width: 10, height: 10 },
];
const linesBetweenRectangles = [
  { x1: 35, x2: 70, y1: 50, y2: 35 },
  { x1: 70, x2: 55, y1: 35, y2: 55 },
];
const rectanglesToAvoid = [
  { x: 40, y: 20, width: 10, height: 10 },
  { x: 30, y: 60, width: 10, height: 20 },
  { x: 30, y: 50, width: 20, height: 20 },
];
const outlineList = bubbles.createOutline(
  BubbleSet.addPadding(rectanglesToInclude, pad),
  BubbleSet.addPadding(rectanglesToAvoid, pad),
  linesBetweenRectangles,
);
// outline is a path that can be used for the attribute d of a SVG path element
const outline = new PointPath(outlineList).transform([
  new ShapeSimplifier(0.0),  // removes path points by removing (near) co-linear points
  new BSplineShapeGenerator(),  // smoothes the output shape using b-splines
  new ShapeSimplifier(0.0),  // removes path points by removing (near) co-linear points
]);
const svgPath = document.getElementById('mypath');
svgPath.setAttribute('d', `${outline}`);

HTML 类似于:

<!DOCTYPE html>
<html>
<head>
  <script async src="index.js" type="module"></script>
</head>
<body>
<svg>
  <path id="mypath" fill="#e41a1c" stroke="black"></path>
</svg>
</body>
</html>

BubbleSets 的工作原理是创建所有元素的完整边界框的势场。潜力大致由到要包含的最近元素的距离定义,并受到到要排除的元素的距离的惩罚。沿着势能具有特定阈值的场行走来创建初始轮廓。该结果作为简单的控制点数组存储在

outlineList
中。这个初始轮廓通常相当崎岖、嘈杂,并且有许多冗余点。为此,我们将列表转换为
PointPath
,它是一个包装器,可以通过
transform
函数轻松操作点。我们应用两种变换:删除共线点以消除冗余点,并通过 BSplines 平滑曲线。您可以在此处查看 BSpline 简化器的实现:https://github.com/JosuaKrause/bubblesets-js/blob/58cb0d5b3d4962810635019e9d917d0b65f7c076/bubblesets.js#L2467-L2561

您问的是 Catmull-Rom 样条线。它们没有针对 JavaScript 版本实现,但您可以在 Java 版本中看到实现:https://github.com/JosuaKrause/Bubble-Sets/blob/41c3218491e9e7b38b69c978fe9afd2bd21e7a65/src/main/java/setvis/shape/CardinalSplineGenerator。爪哇 Java 和 JavaScript 版本的转换方法是相同的,因此转换实现应该相对简单。

© www.soinside.com 2019 - 2024. All rights reserved.