如何用Plots.surface绘制一个参数曲面S(u,v)?


#1

本人初学写代码,例如以下一个直纹面只绘制出了控制点网格,求助plot出曲面的规范代码,多谢:pray:

#ruled surface

using Plots

p00=[0,0,0]
p10=[6,1,1]
p01=[1,5,7]
p11=[7,7,4]
Px=[0 1
   6 7]
Py=[0 5
   1 7]
Pz=[0 7
   1 4]

k=32
u=range(0,stop=1,length=k)
v=range(0,stop=1,length=k)

x(u,v)=(Px*[1-u,u])'*[1-v,v]
y(u,v)=(Py*[1-u,u])'*[1-v,v]
z(u,v)=(Pz*[1-u,u])'*[1-v,v]
S(u,v)=[x(u,v),y(u,v),z(u,v)]

plot(Px,Py,Pz,xlabel="x",ylabel="y",zlabel="z",legend=false)
plot!(Px',Py',Pz')

#2

不是很懂你想怎么画

我的理解

X = Px * hcat(1 .- u, u)' * hcat(1 .- v, v)
# 2×2 Array{Float64,2}:
#    5.16129   10.8387
#    101.161   106.839
u # 32x1
hcat(1 .- u ,u) # 32x2
hcat(1 .- u ,u)' # 2x32
Px # 2x2
hcat(1 .- v, v) # 32x2
Px * hcat(1 .- u ,u)' * hcat(1 .- v, v) # 2x2 * 2x32 * 32x2 = 2x2

最后的 X 是个 2x2 的矩阵,怎么画曲面?


#3

我习惯上是这么画的,先定义映射(标量形式):

x(u, v) = cos(u)
y(u, v) = sin(u) * cos(v)
z(u, v) = sin(u) * sin(v)

给定参数范围并使用广播生成所需的矩阵:

U = 0:0.1:2π
V = 0:0.1:π
XX = x.(U, V')
YY = y.(U, V')
ZZ = z.(U, V')

最后再画图:

PyPlot.surf(XX, YY, ZZ)

在这里我用 PyPlot,在 Plots 里我找不到对应的函数,Makie 里我记得也有。


#4

pyplot 里用 surface

# 上面的代码

pyplot()
surface(XX, YY, ZZ)


#5

多谢回复,可能是我写的不规范,上面x(u,v)是Px 矩阵乘向量后转制再乘向量,结果应该是标量吧?


#6

谢谢回复!等我搞定PyCall错误按您的代码试试


#7

' 其实是共轭转置,而不仅仅是转置。只因为绘图中出现的数据一般都是实数,我才在广播中偷懒直接使用共轭转置,更规范的写法我觉得应该是使用 transpose 来转置传入函数的第二个参数。


#8

再次感谢,Makie真的好用。想再请教下里面的shading 怎么改变光源方向? 如下图让其高光位置更好看点,还有能否调整透视角度即焦距或FOV,让其透视变形小点呢?