0
f(x,y)= (1/25)*(20-x)/x   10<x<20, x/2 <y <x
        0                   o.t

I have to create this image through this expression. enter image description here

but enter image description here

x <- seq(10, 20, length=20)
y <- seq(10, 20, length=20)
f <- function(x,y){(1/25)*(20-x)/5}
z <- outer(x,y,f)
persp(x,y,z,theta=30,phi=30, expand=0.5,col=rainbow(19), border=NA)

what is wrong?

SRhm
  • 459
  • 1
  • 5
  • 11
Kim HEE
  • 1
  • 1
  • Welcome to Stack Overflow! –  Oct 21 '18 at 19:00
  • Welcome. Please check out https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example for best practices when posting questions. – hmhensen Oct 25 '18 at 20:12
  • If the answer below is satisfactory, you should "accept" it. If not, you should explain what else you want, and its author may try to improve it. – user2554330 Oct 28 '18 at 09:27

2 Answers2

0

You should mask z based on the constraint. As a suggestion, you can use an amazing interactive rgl package in R.

#source: https://stackoverflow.com/questions/50079316/plot3d-how-to-change-z-axis-surface-color-to-heat-map-color
map2color <- function(x, pal, limits = range(x,na.rm=T)){
  pal[findInterval(x, seq(limits[1], limits[2], length.out = length(pal) + 1), 
               all.inside=TRUE)]
}

x <- seq(10, 20, length=20)
y <- seq(10, 20, length=20)
mask <- sapply(x,function(m) sapply(y,function(n) if((n>m/2)&(n<m)){(1/25)*(20-m)/5}else{ NA }))
z <- outer(x,y,f)
z <- z * mask
#persp(x,y,z, col= map2color(z, rainbow(100)),border = NA)
library(rgl)
persp3d(x,y,z,col = map2color(z, rainbow(100)),theta=30,phi=30)

enter image description here enter image description here

SRhm
  • 459
  • 1
  • 5
  • 11
0

@SRhm's answer is probably the best choice, but if you want to live on the bleeding edge, you can get rid of the jagged diagonal edge using a development version of rgl (from R-forge), at least version 0.100.8.

This version supports triangulations with boundaries using the tripack package. So you set up a grid of values over the x-y range, then define the boundaries of the region using the equations, and you get smooth edges. For example:

library(tripack)
library(rgl)
g <- expand.grid(x=10:20, y=5:20)
keep <- with(g, 10 < x & x < 20 & x/2 < y & y < x)
g2 <- g[keep,]
tri <- tri.mesh(g2)

# Set up boundary constraints
cx <- c(10:20, 20: 10)
cy <- c(seq(5, 10, len=11), 20:10)
tri2 <- add.constraint(tri, cx, cy, reverse = TRUE)

# This isn't necessary, but shows where the formula will be evaluated
plot(tri2)

triangulation

It might be better to fill in some of the left and right edges with more points to avoid those big triangles, but skip that for now.

z <- with(tri2, (1/25)*(20-x)/x)
# Now plot it, using the map2color function @SRhm found:
#source: https://stackoverflow.com/questions/50079316/plot3d-how-to-change-z-axis-surface-color-to-heat-map-color
map2color <- function(x, pal, limits = range(x,na.rm=T)){
  pal[findInterval(x, seq(limits[1], limits[2], length.out = length(pal) + 1), 
               all.inside=TRUE)]
}
persp3d(tri2, z, col = map2color(z, rainbow(100)))

After rotation, you get this view:

persp3d view

user2554330
  • 37,248
  • 4
  • 43
  • 90