从顶点看凸包图

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

我想制作凸包图形,为 Gnuplot 提供连接图形表面的顶点。

我一直在测试,但我没有任何明确的方法来做到这一点。

我可以用这个脚本绘制点:

set encoding iso_8859_1
set terminal postscript eps enhanced color  size 4.0in,4.0in #"Helvetica" 16
set output "RG1.eps"
set view 50,220
unset colorbox
splot "convex1.dat" with lines notitle ,\
"convex1.dat" u 1:2:3 with points palette pointsize 3 pointtype 7

其中凸1.dat包含这些点

0   0   0
0   0   0.285957
0   0.285957    0.285957
0   0.3812378724    0.1906189362
0   0.571914    0
0.1906761276    0.3812378724    0.1906189362
0.285957    0.285957    0.285957
0.571914    0   0
0.571914    0   0.285957 

这个脚本的表示是:

我可以在 Mathematica 环境中用这些点制作凸包,并创建我正在寻找的图形类型:

问题是:如何使用 Gnuplot 制作凸包,如 Mathematica 图形,以及如何使用透明度来比较具有相同轴的两个凸包来制作图形?

gnuplot computational-geometry convex-hull
2个回答
1
投票

Gnuplot 主要是结构化数值数据的渲染器;它并不是一个数学处理系统,也不是一个几何数据的渲染器。

pm3d
splot
样式允许您绘制任意多边形集合,但它不会删除隐藏的表面,更不用说基于多个多边形相交的复杂渲染了。事实上,文档本身说:

Gnuplot 不是计算填充交集的虚拟现实工具 多边形网格。

对于这类事情,您需要使用实际的数学处理包(例如 Mathematica!),它可以输出为矢量格式,然后直接使用它,而不是通过 Gnuplot。


0
投票

也许您甚至可以仅使用 gnuplot-only 来完成它,但是,可能相当麻烦、冗长且缓慢。 因此,这里建议如何在外部帮助下完成此操作:QHull

数据:

SO50699586.dat
(OP的数据)

0              0              0
0              0              0.285957
0              0.285957       0.285957
0              0.3812378724   0.1906189362
0              0.571914       0
0.1906761276   0.3812378724   0.1906189362
0.285957       0.285957       0.285957
0.571914       0              0
0.571914       0              0.285957 

对于程序

qhull
,您需要以下输入格式:

3   # dimension 3D
9   # number or following x,y,z points
x0 y0 z1
x1 y1 z1
...
x8 y8 y8

命令

qhull -G input
的输出将具有以下格式:

{appearance {+edge -evert linewidth 2} LIST #  | qhull -G
{ OFF 3 1 1 # f1
  0.5719        0 -3.967e-15 
       0   0.5719 -3.967e-15 
       0        0 -3.967e-15 
3 0 1 2      0.5      0.5        0 1.0 }
{ OFF 4 1 1 # f2
  0.5719 -3.967e-15    0.286 
  0.5719 -3.967e-15        0 
       0 -3.967e-15        0 
       0 -3.967e-15    0.286 
4 0 1 2 3      0.5        0      0.5 1.0 }
{ OFF 4 1 1 # f5
   0.286    0.286    0.286 
2.805e-15   0.5719        0 
  0.5719 2.805e-15        0 
  0.5719 2.805e-15    0.286 
4 0 1 2 3   0.8536   0.8536      0.5 1.0 }
{ OFF 3 1 1 # f11
   0.286    0.286    0.286 
       0    0.286    0.286 
       0   0.5719 2.805e-15 
3 0 1 2      0.5   0.8536   0.8536 1.0 }
{ OFF 4 1 1 # f3
-3.967e-15   0.5719        0 
-3.967e-15    0.286    0.286 
-3.967e-15        0    0.286 
-3.967e-15        0        0 
4 0 1 2 3        0      0.5      0.5 1.0 }
{ OFF 4 1 1 # f10
       0    0.286    0.286 
   0.286    0.286    0.286 
  0.5719        0    0.286 
       0        0    0.286 
4 0 1 2 3      0.5      0.5        1 1.0 }
}

不幸的是,这种格式不适合用 gnuplot 直接绘图。也许有更适合 gnuplot 的输出格式。 所以,你需要:

  • 跳过第一行
  • 从以
    {
    开头的其他行中提取第一个数字,该数字表示后续面的顶点数(主要是 3 或 4),但不要将该行添加到表格中
  • 将以下 3 或 4(或可能更多)行绘制到表/数据块
    $Data
  • 继续处理整个文件

因此数据块

$Data
看起来像这样:


0.5719 0 -3.967e-15
0 0.5719 -3.967e-15
0 0 -3.967e-15


0.5719 -3.967e-15 0.286
0.5719 -3.967e-15 0
0 -3.967e-15 0
0 -3.967e-15 0.286


0.286 0.286 0.286
2.805e-15 0.5719 0
0.5719 2.805e-15 0
0.5719 2.805e-15 0.286


0.286 0.286 0.286
0 0.286 0.286
0 0.5719 2.805e-15


-3.967e-15 0.5719 0
-3.967e-15 0.286 0.286
-3.967e-15 0 0.286
-3.967e-15 0 0


0 0.286 0.286
0.286 0.286 0.286
0.5719 0 0.286
0 0 0.286

这些是需要用 gnuplot 绘制的多边形。 gnuplot>=5.4.0(2020 年 7 月)的绘图风格为

with polygons
。也许还有通过
with pm3d
的 gnuplot 5.2 解决方案。 船体的计算速度相当快。约1000点在约2秒内完成。

脚本:(适用于 gnuplot>=5.4.0,2020 年 7 月)

### plot convex 3D-hull (with external help: QHull)
reset session

FILE = "SO50699586.dat"

HULL_IN  = FILE[1:strlen(FILE)-3].'qhin'   # qhull input
HULL_OUT = FILE[1:strlen(FILE)-3].'hull'   # qhull output

stats FILE u 0 nooutput   # extract number of points
set table HULL_IN
    plot '+' every ::::1 u (int($0)?STATS_records:3) w table, \
         FILE u 1:2:3 w table
unset table

# run qhull
system(qhull -G <'.HULL_IN.' >'.HULL_OUT)

set table $Data
    plot HULL_OUT skip 1 u (strcol(1) eq '{' ? (p=$3,c=0,'') : \
         (c=c+1,c<=p?sprintf("%g %g %g",$1,$2,$3):'')) w table
unset table

set view equal xyz
set view 60,210, 1.3
set pm3d depth
set pm3d border lc "black" lw 0.5
set key noautotitle
set xyplane relative 0

splot for [i=0:*] $Data index i u 1:2:3 w polygons fc rgb int(0x1000000*rand(0)*0.5+0x777777)
### end of script

结果:

脚本:(用于在球体上生成 1000 个随机点。然后运行上面的脚本)

# create some random points (on a sphere surface)
FILE = "SO50699586.dat"
set table FILE
    set sample 1000
    plot '+' u (a=rand(0)*2*pi,b=rand(0)*pi,cos(a)*sin(b)):(sin(a)*sin(b)):(cos(b)) w table
unset table

结果:(在 <2 seconds on my 8 year old laptop)

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