所以我正在做一个项目,我们使用凸包对点进行分组,并使用 Catmull-Rom 样条线使其更圆,如图所示:
现在我的下一个任务是将可以看到的路径连接到凸包,这样我看起来像这样:
所以我不知道如何解决这个问题,我想创建像bubblests中那样连接圆圈的路径,这些弯曲的路径,但我不确定我应该看什么数学,我想自己做一个不仅仅是使用实现它的库,我还查看了以下内容:\
https://github.com/MultiSetVis/MultiSetVis.github.io - 特别是简单的散点图示例。
https://bubblesets-js.josuakrause.com/
但我仍然不确定他们是如何做到这一点的,所以如果有人有任何想法,我会洗耳恭听。
您发布的第二个链接实际上是一个 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 版本的转换方法是相同的,因此转换实现应该相对简单。