我有一个完整城市的3D模型,并希望展示一个 这些建筑的等距视图。我为此使用gnuplot多边形, 因为我认为我不能将pm3d用于坐标为的多边形 不是一个明确定义的网格。多边形以颜色显示 对应于他们获得的平均太阳辐照度。一世 还将地面多边形显示为线框,主要用于设置xrange, yrange和zrange自动。
从遥远的地方看起来不错,但是当你放大时,你会看到它 一些多边形的深度排序是错误的。
您是否知道如何以正确的顺序显示这些多边形?
像this这样的东西会很棒,但它似乎只适用于splot
。
这是一个用于查看问题的Gnuplot文件(2个建筑物和4个屋顶):
set style line 1 linecolor rgbcolor "#777777" linewidth 1
set style increment user
set palette file "-"
0.00000 0.23137 0.22353 0.64314
0.17990 0.47843 0.34510 0.71765
0.32010 0.34902 0.17647 0.55686
0.43990 0.40784 0.10980 0.36471
0.59010 0.46275 0.09020 0.16863
0.78000 0.86667 0.41569 0.24314
0.92990 0.92549 0.66667 0.33725
1.00000 0.97647 0.91765 0.82745
e
set cbrange [50:150]
set cbtics 25
set format cb "%.0f W/m²"
unset xtics
unset ytics
unset ztics
unset border
set colorbox
kzoom=1.0
phi=30.0
theta=60.0
set xyplane 0 # removes the offset of the xy plane
set view equal xyz # force equal units to all three axes
set view theta,phi,kzoom
set object 1 polygon from \
2.0,0.0,3.0 to \
3.0,0.0,3.5 to \
3.0,2.0,3.5 to \
2.0,2.0,3.0 to \
2.0,0.0,3.0
set object 1 fill solid 0.9 border lw 2 fc palette cb 128.1315 front
set object 2 polygon from \
4.0,0.0,3.0 to \
4.0,2.0,3.0 to \
3.0,2.0,3.5 to \
3.0,0.0,3.5 to \
4.0,0.0,3.0
set object 2 fill solid 0.9 border lw 2 fc palette cb 128.62192 front
set object 3 polygon from \
2.0,0.0,0.0 to \
4.0,0.0,0.0 to \
4.0,0.0,3.0 to \
3.0,0.0,3.5 to \
2.0,0.0,3.0 to \
2.0,0.0,0.0
set object 3 fill solid 0.9 border lw 2 fc palette cb 100.545204
set object 4 polygon from \
4.0,0.0,0.0 to \
4.0,2.0,0.0 to \
4.0,2.0,3.0 to \
4.0,0.0,3.0 to \
4.0,0.0,0.0
set object 4 fill solid 0.9 border lw 2 fc palette cb 85.58082
set object 5 polygon from \
4.0,2.0,0.0 to \
2.0,2.0,0.0 to \
2.0,2.0,3.0 to \
3.0,2.0,3.5 to \
4.0,2.0,3.0 to \
4.0,2.0,0.0
set object 5 fill solid 0.9 border lw 2 fc palette cb 55.88219
set object 6 polygon from \
2.0,2.0,0.0 to \
2.0,0.0,0.0 to \
2.0,0.0,3.0 to \
2.0,2.0,0.0
set object 6 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 7 polygon from \
2.0,2.0,0.0 to \
2.0,0.0,3.0 to \
2.0,2.0,3.0 to \
2.0,2.0,0.0
set object 7 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 8 polygon from \
0.0,0.0,3.0 to \
1.0,0.0,3.5 to \
1.0,2.0,3.5 to \
0.0,2.0,3.0 to \
0.0,0.0,3.0
set object 8 fill solid 0.9 border lw 2 fc palette cb 128.1315 front
set object 9 polygon from \
2.0,0.0,3.0 to \
2.0,2.0,3.0 to \
1.0,2.0,3.5 to \
1.0,0.0,3.5 to \
2.0,0.0,3.0
set object 9 fill solid 0.9 border lw 2 fc palette cb 128.62192 front
set object 10 polygon from \
0.0,0.0,0.0 to \
2.0,0.0,0.0 to \
2.0,0.0,3.0 to \
1.0,0.0,3.5 to \
0.0,0.0,3.0 to \
0.0,0.0,0.0
set object 10 fill solid 0.9 border lw 2 fc palette cb 100.545204
set object 11 polygon from \
2.0,0.0,0.0 to \
2.0,2.0,0.0 to \
2.0,2.0,3.0 to \
2.0,0.0,3.0 to \
2.0,0.0,0.0
set object 11 fill solid 0.9 border lw 2 fc palette cb 85.58082
set object 12 polygon from \
2.0,2.0,0.0 to \
0.0,2.0,0.0 to \
0.0,2.0,3.0 to \
1.0,2.0,3.5 to \
2.0,2.0,3.0 to \
2.0,2.0,0.0
set object 12 fill solid 0.9 border lw 2 fc palette cb 55.88219
set object 13 polygon from \
0.0,2.0,0.0 to \
0.0,0.0,0.0 to \
0.0,0.0,3.0 to \
0.0,2.0,0.0
set object 13 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 14 polygon from \
0.0,2.0,0.0 to \
0.0,0.0,3.0 to \
0.0,2.0,3.0 to \
0.0,2.0,0.0
set object 14 fill solid 0.9 border lw 2 fc palette cb 85.25754
splot "-" with lines notitle ls 1, NaN notitle palette
2.0 0.0 0.0
2.0 2.0 0.0
4.0 2.0 0.0
4.0 0.0 0.0
2.0 0.0 0.0
0.0 0.0 0.0
0.0 2.0 0.0
2.0 2.0 0.0
2.0 0.0 0.0
0.0 0.0 0.0
e
pause mouse
感谢您的关注!
答案 0 :(得分:3)
我找不到一个选项来说服gnuplot它应该自动设置多边形对象的深度顺序。我发现的唯一方法是以正确的顺序定义对象。然后gnuplot将它们中的每一个绘制在前一个上面,这导致了预期的结果。
在删除front
说明符后获取示例多边形,此方法会更改原始图片:
到这个(删除front
后):
到这一个(排序后):
我认为第三张照片就是你想要的。
我使用python脚本对多边形进行排序,基本上这样做:
set object x polygon from
行开头。set view theta, phi
的gnuplot一样,它会围绕x和z轴旋转多边形(暂时只是为了排序)。x
中的set object x polygon
。set object
行的排序多边形数据。请注意,此方法仅适用于静态图片。如果您想以交互方式旋转图片,它将无效。
另请注意,如果该方法对您的完整数据文件不起作用,我可能搞乱了旋转矩阵或 轴分配:)
我附加了python脚本,绘图文件和数据文件" plot_raw.dat"和" plot_sorted.dat"供参考。
# poly.py
from math import cos, sin, pi
from re import sub, match, findall
class Polygon:
def __init__(self):
self.firstLine = ""
self.points = []
self.lastLine = ""
def __str__(self):
pointStrings = [",".join(map(str,point)) for point in self.points]
s = ""
s += self.firstLine
s += " to \\\n".join(pointStrings)
s += "\n"
s += self.lastLine
return s
def readObjectFromFile(self, f, firstObjectLine):
self.firstLine = firstObjectLine
line = f.readline()
while not match("set",line):
coordinates = findall("[\d.]+", line)
coordinates = tuple(float(x) for x in coordinates)
self.points.append(coordinates)
line = f.readline()
self.lastLine = line
return self
def meanAfterRotation(self, theta, phi):
cx = 0.0
cy = 0.0
cz = 0.0
theta = theta*pi/180.0
phi = phi*pi/180.0
for point in self.points:
x,y,z = point
x,y,z = (x, y*cos(theta) - z*sin(theta), y*sin(theta) + z*cos(theta))
x,y,z = (x*cos(phi) - y*sin(phi), x*sin(phi) + y*cos(phi), z)
cx, cy, cz = (cx + x, cy + y, cz + z)
n = len(self.points)
return (cx/n, cy/n, cz/n)
def setPosition(self, posIndex):
self.firstLine = sub("(\d+)", str(posIndex), self.firstLine, 1)
self.lastLine = sub("(\d+)", str(posIndex), self.lastLine, 1)
polygons = []
with open("poly_raw.dat") as f:
line = f.readline()
while line:
if line.strip() != "":
polygons.append(Polygon().readObjectFromFile(f,line))
line = f.readline()
polygons.sort(key = lambda x: x.meanAfterRotation(60,30)[1], reverse = True)
pos = 1
for p in polygons:
p.setPosition(pos)
pos += 1
for p in polygons:
print(p)
gnuplot脚本:
# poly.plt, gnuplot 4.6
# Does not work when interactively rotating the picture.
set style line 1 linecolor rgbcolor "#777777" linewidth 1
set style increment user
set palette file "-"
0.00000 0.23137 0.22353 0.64314
0.17990 0.47843 0.34510 0.71765
0.32010 0.34902 0.17647 0.55686
0.43990 0.40784 0.10980 0.36471
0.59010 0.46275 0.09020 0.16863
0.78000 0.86667 0.41569 0.24314
0.92990 0.92549 0.66667 0.33725
1.00000 0.97647 0.91765 0.82745
e
set cbrange [50:150]
set cbtics 25
set format cb "%.0f W/m²"
unset xtics
unset ytics
unset ztics
unset border
set colorbox
kzoom=1.0
phi=30.0
theta=60.0
set xyplane 0 # removes the offset of the xy plane
set view equal xyz # force equal units to all three axes
set view theta,phi,kzoom
#load "poly_raw.dat"
load "poly_sorted.dat"
set terminal png
#set output "raw.png"
set output "sorted.png"
splot "-" with lines notitle ls 1, NaN notitle palette
2.0 0.0 0.0
2.0 2.0 0.0
4.0 2.0 0.0
4.0 0.0 0.0
2.0 0.0 0.0
0.0 0.0 0.0
0.0 2.0 0.0
2.0 2.0 0.0
2.0 0.0 0.0
0.0 0.0 0.0
e
删除front
说明符后的未排序多边形数据:
set object 1 polygon from \
2.0,0.0,3.0 to \
3.0,0.0,3.5 to \
3.0,2.0,3.5 to \
2.0,2.0,3.0 to \
2.0,0.0,3.0
set object 1 fill solid 0.9 border lw 2 fc palette cb 128.1315
set object 2 polygon from \
4.0,0.0,3.0 to \
4.0,2.0,3.0 to \
3.0,2.0,3.5 to \
3.0,0.0,3.5 to \
4.0,0.0,3.0
set object 2 fill solid 0.9 border lw 2 fc palette cb 128.62192
set object 3 polygon from \
2.0,0.0,0.0 to \
4.0,0.0,0.0 to \
4.0,0.0,3.0 to \
3.0,0.0,3.5 to \
2.0,0.0,3.0 to \
2.0,0.0,0.0
set object 3 fill solid 0.9 border lw 2 fc palette cb 100.545204
set object 4 polygon from \
4.0,0.0,0.0 to \
4.0,2.0,0.0 to \
4.0,2.0,3.0 to \
4.0,0.0,3.0 to \
4.0,0.0,0.0
set object 4 fill solid 0.9 border lw 2 fc palette cb 85.58082
set object 5 polygon from \
4.0,2.0,0.0 to \
2.0,2.0,0.0 to \
2.0,2.0,3.0 to \
3.0,2.0,3.5 to \
4.0,2.0,3.0 to \
4.0,2.0,0.0
set object 5 fill solid 0.9 border lw 2 fc palette cb 55.88219
set object 6 polygon from \
2.0,2.0,0.0 to \
2.0,0.0,0.0 to \
2.0,0.0,3.0 to \
2.0,2.0,0.0
set object 6 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 7 polygon from \
2.0,2.0,0.0 to \
2.0,0.0,3.0 to \
2.0,2.0,3.0 to \
2.0,2.0,0.0
set object 7 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 8 polygon from \
0.0,0.0,3.0 to \
1.0,0.0,3.5 to \
1.0,2.0,3.5 to \
0.0,2.0,3.0 to \
0.0,0.0,3.0
set object 8 fill solid 0.9 border lw 2 fc palette cb 128.1315
set object 9 polygon from \
2.0,0.0,3.0 to \
2.0,2.0,3.0 to \
1.0,2.0,3.5 to \
1.0,0.0,3.5 to \
2.0,0.0,3.0
set object 9 fill solid 0.9 border lw 2 fc palette cb 128.62192
set object 10 polygon from \
0.0,0.0,0.0 to \
2.0,0.0,0.0 to \
2.0,0.0,3.0 to \
1.0,0.0,3.5 to \
0.0,0.0,3.0 to \
0.0,0.0,0.0
set object 10 fill solid 0.9 border lw 2 fc palette cb 100.545204
set object 11 polygon from \
2.0,0.0,0.0 to \
2.0,2.0,0.0 to \
2.0,2.0,3.0 to \
2.0,0.0,3.0 to \
2.0,0.0,0.0
set object 11 fill solid 0.9 border lw 2 fc palette cb 85.58082
set object 12 polygon from \
2.0,2.0,0.0 to \
0.0,2.0,0.0 to \
0.0,2.0,3.0 to \
1.0,2.0,3.5 to \
2.0,2.0,3.0 to \
2.0,2.0,0.0
set object 12 fill solid 0.9 border lw 2 fc palette cb 55.88219
set object 13 polygon from \
0.0,2.0,0.0 to \
0.0,0.0,0.0 to \
0.0,0.0,3.0 to \
0.0,2.0,0.0
set object 13 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 14 polygon from \
0.0,2.0,0.0 to \
0.0,0.0,3.0 to \
0.0,2.0,3.0 to \
0.0,2.0,0.0
set object 14 fill solid 0.9 border lw 2 fc palette cb 85.25754
运行python poly.py > poly_sorted.dat
set object 1 polygon from \
4.0,0.0,0.0 to \
4.0,2.0,0.0 to \
4.0,2.0,3.0 to \
4.0,0.0,3.0 to \
4.0,0.0,0.0
set object 1 fill solid 0.9 border lw 2 fc palette cb 85.58082
set object 2 polygon from \
4.0,2.0,0.0 to \
2.0,2.0,0.0 to \
2.0,2.0,3.0 to \
3.0,2.0,3.5 to \
4.0,2.0,3.0 to \
4.0,2.0,0.0
set object 2 fill solid 0.9 border lw 2 fc palette cb 55.88219
set object 3 polygon from \
2.0,2.0,0.0 to \
2.0,0.0,0.0 to \
2.0,0.0,3.0 to \
2.0,2.0,0.0
set object 3 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 4 polygon from \
2.0,2.0,0.0 to \
2.0,0.0,3.0 to \
2.0,2.0,3.0 to \
2.0,2.0,0.0
set object 4 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 5 polygon from \
2.0,0.0,0.0 to \
2.0,2.0,0.0 to \
2.0,2.0,3.0 to \
2.0,0.0,3.0 to \
2.0,0.0,0.0
set object 5 fill solid 0.9 border lw 2 fc palette cb 85.58082
set object 6 polygon from \
2.0,2.0,0.0 to \
0.0,2.0,0.0 to \
0.0,2.0,3.0 to \
1.0,2.0,3.5 to \
2.0,2.0,3.0 to \
2.0,2.0,0.0
set object 6 fill solid 0.9 border lw 2 fc palette cb 55.88219
set object 7 polygon from \
2.0,0.0,0.0 to \
4.0,0.0,0.0 to \
4.0,0.0,3.0 to \
3.0,0.0,3.5 to \
2.0,0.0,3.0 to \
2.0,0.0,0.0
set object 7 fill solid 0.9 border lw 2 fc palette cb 100.545204
set object 8 polygon from \
0.0,2.0,0.0 to \
0.0,0.0,0.0 to \
0.0,0.0,3.0 to \
0.0,2.0,0.0
set object 8 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 9 polygon from \
4.0,0.0,3.0 to \
4.0,2.0,3.0 to \
3.0,2.0,3.5 to \
3.0,0.0,3.5 to \
4.0,0.0,3.0
set object 9 fill solid 0.9 border lw 2 fc palette cb 128.62192
set object 10 polygon from \
0.0,2.0,0.0 to \
0.0,0.0,3.0 to \
0.0,2.0,3.0 to \
0.0,2.0,0.0
set object 10 fill solid 0.9 border lw 2 fc palette cb 85.25754
set object 11 polygon from \
0.0,0.0,0.0 to \
2.0,0.0,0.0 to \
2.0,0.0,3.0 to \
1.0,0.0,3.5 to \
0.0,0.0,3.0 to \
0.0,0.0,0.0
set object 11 fill solid 0.9 border lw 2 fc palette cb 100.545204
set object 12 polygon from \
2.0,0.0,3.0 to \
3.0,0.0,3.5 to \
3.0,2.0,3.5 to \
2.0,2.0,3.0 to \
2.0,0.0,3.0
set object 12 fill solid 0.9 border lw 2 fc palette cb 128.1315
set object 13 polygon from \
2.0,0.0,3.0 to \
2.0,2.0,3.0 to \
1.0,2.0,3.5 to \
1.0,0.0,3.5 to \
2.0,0.0,3.0
set object 13 fill solid 0.9 border lw 2 fc palette cb 128.62192
set object 14 polygon from \
0.0,0.0,3.0 to \
1.0,0.0,3.5 to \
1.0,2.0,3.5 to \
0.0,2.0,3.0 to \
0.0,0.0,3.0
set object 14 fill solid 0.9 border lw 2 fc palette cb 128.1315
答案 1 :(得分:2)
我知道这是一个古老的问题,但是现在有一个gnuplot设置,我认为它将执行所要求的操作:
set pm3d depthorder base
这将pm3d多边形投影到基本平面上(通常为z = 0),然后按距视点的距离进行排序,从而对它们进行排序。该算法旨在处理3D盒子等较简单的情况,但是您的模型非常接近,只要是基于盒子的盒子,我认为它将受益于相同的处理方法。这是“ boxes3d”演示中的示例。
答案 2 :(得分:0)
尽管这是个老问题,但我认为在这个意义上已经取得了一些进展。我使用function returnImage(i) {
let num = 1;
if (i > 30)
num = parseInt((parseInt(i / 25, 10) * 25 - 1) / 25, 10) + 2;
return 'image' + num;
}
console.log(returnImage(10));
console.log(returnImage(30));
console.log(returnImage(49));
console.log(returnImage(50));
console.log(returnImage(74));
console.log(returnImage(100));
console.log(returnImage(125));
console.log(returnImage(130));
console.log(returnImage(200));
console.log(returnImage(300));
console.log(returnImage(490));
数据而不是多边形。以特定顺序创建面可实现正确的z顺序。我使用了一个名为x-y-z
house.dat
和这个0.0000 0.0000 0.0000
2.0000 0.0000 0.0000
2.0000 0.0000 3.0000
1.0001 0.0000 4.0000
0.9999 0.0000 4.0000
0.0000 0.0000 3.0000
0.0000 0.0000 0.0000
2.0000 0.0000 0.0000
2.0000 2.0000 0.0000
2.0000 2.0000 3.0000
1.0001 2.0000 4.0000
1.0001 0.0000 4.0000
2.0000 0.0000 3.0000
2.0000 0.0000 0.0000
2.0000 2.0000 0.0000
0.0000 2.0000 0.0000
0.0000 2.0000 3.0000
0.9999 2.0000 4.0000
1.0001 2.0000 4.0000
2.0000 2.0000 3.0000
2.0000 2.0000 0.0000
2.0000 0.0000 0.0000
0.0000 0.0000 0.0000
0.0000 0.0000 3.0000
0.9999 0.0000 4.0000
0.9999 2.0000 4.0000
0.0000 2.0000 3.0000
0.0000 2.0000 0.0000
2.0000 0.0000 0.0000
脚本
gnuplot
要获得此结果:
正式适用于任何角度: