How to increase smoothness of spheres3d in rgl

save rgl 3d plot
plot3d r
rgl 2d plot
rgl add points
rgl volcano
rgl html

When I use rgl::spheres3d(), the rendered spheres have clunky facetted edges.

spheres = data.frame(x = c(1,2,3), y = c(1,3,1),
                     color = c("#992222" , "#222299", "#229922"))
open3d()
spheres3d(spheres$x, spheres$y, radius = 1, color = spheres$color)

Setting material3d(smooth = TRUE, line_antialias = TRUE) does not improve this. Increasing the radius does not help either. Is there any way to increase the smoothness with which they are drawn?

Expanding on cuttlefish44's excellent answer, I found a parameterization that works better - i.e. it has no defect at the poles (the black artifact on the lightblue sphere in the image).

library(rgl)
sphere.f <- function(x0 = 0, y0 = 0, z0 = 0, r = 1, n = 101, ...){
  f <- function(s, t) cbind(r * cos(s) * cos(t) + x0,
                            r * sin(s) * cos(t) + y0, 
                            r * sin(t) + z0)
  persp3d(f, slim = c(0, pi), tlim = c(0, 2*pi), n = n, add = T, ...)
}


sphere1.f <- function(x0 = 0, y0 = 0, z0 = 0, r = 1, n = 101, ...){
  f <- function(s,t){ 
    cbind(   r * cos(t)*cos(s) + x0,
             r *        sin(s) + y0,
             r * sin(t)*cos(s) + z0)
  }
  persp3d(f, slim = c(-pi/2,pi/2), tlim = c(0, 2*pi), n = n, add = T, ...)
}


sphere.f( -1.5,0, col = "lightblue")
sphere1.f( 1.5,0, col = "pink")

The image:

spheres: add sphere set shape in rgl: 3D Visualization Using OpenGL, spheres3d(x, y = NULL, z = NULL, radius = 1, ) rgl.spheres(x, y = NULL, z  Package rgl includes a very useful function ellipse3d, which can return an ellipsoid that cover like 95% percent of the points in 3D. Then this object can be used in rgl::plot3d to plot it out. My

A much simpler approach is to use subdivision3d(). Here, depth=4 isn't all that smooth, but you could increase that.

library(rgl)
sphere <- subdivision3d(cube3d(),depth=4)
sphere$vb[4,] <- apply(sphere$vb[1:3,], 2, function(x) sqrt(sum(x^2)))
open3d()
shade3d(sphere, col="red")

[PDF] rgl, This has the effect of making the surface of the object appear smooth rather spheres3d(center, radius = 1, col = "white", alpha = 0.2) "pull" Pulling on the mouse wheel increases magnification, i.e. “pulls the scene closer”. rgl.material() is called for the side effect of setting the material properties. It returns a value invisibly which is not intended for use by the user. Users should use material3d() to query material properties.

Although rgl::spheres3d() can't do this, an alternative is to write your own function to draw spheres. Here is a function that renders a sphere as a grid of quadrilaterals spaced at equal degrees of latitude and longitude.

drawSphere = function(xc=0, yc=0, zc=0, r=1, lats=50L, longs=50L, ...) {
  #xc,yc,zc give centre of sphere, r is radius, lats/longs for resolution
  vertices = vector(mode = "numeric", length = 12L * lats * longs)
  vi = 1L
  for(i in 1:lats) {
    lat0 = pi * (-0.5 + (i - 1) / lats)
    z0   = sin(lat0)*r
    zr0  = cos(lat0)*r
    lat1 = pi * (-0.5 + i / lats)
    z1   = sin(lat1)*r
    zr1  = cos(lat1)*r
    for(j in 1:longs) {
      lng1 = 2 * pi *  (j - 1) / longs
      lng2 = 2 * pi *  (j) / longs
      x1 = cos(lng1)
      y1 = sin(lng1)
      x2 = cos(lng2)
      y2 = sin(lng2)
      vertices[vi] = x1 * zr0 + xc;    vi = vi + 1L
      vertices[vi] = y1 * zr0 + yc;    vi = vi + 1L 
      vertices[vi] = z0 + zc;          vi = vi + 1L
      vertices[vi] = x1 * zr1 + xc;    vi = vi + 1L
      vertices[vi] = y1 * zr1 + yc;    vi = vi + 1L
      vertices[vi] = z1 + zc;          vi = vi + 1L
      vertices[vi] = x2 * zr1 + xc;    vi = vi + 1L
      vertices[vi] = y2 * zr1 + yc;    vi = vi + 1L
      vertices[vi] = z1 + zc;          vi = vi + 1L
      vertices[vi] = x2 * zr0 + xc;    vi = vi + 1L
      vertices[vi] = y2 * zr0 + yc;    vi = vi + 1L
      vertices[vi] = z0 + zc;          vi = vi + 1L
    }
  }
  indices = 1:(length(vertices)/3)
  shade3d(qmesh3d(vertices, indices, homogeneous=F), ...)
}

It should be possible to improve on this, for example using icospheres (i.e. drawing the sphere as a stretched icosohedron). But this version already draws pretty good spheres if you make lats and longs high enough.

An example of the function in action:

spheres = data.frame(x = c(1,2,3), y = c(1,3,1), z=c(0,0,0), color = c("#992222" , "#222299", "#229922"))
open3d() 
material3d(ambient = "black", specular = "grey60", emission = "black", shininess = 30.0)
rgl.clear(type = "lights")
rgl.light(theta = -30, phi = 60, viewpoint.rel = TRUE, ambient = "#FFFFFF", diffuse = "#FFFFFF", specular = "#FFFFFF", x = NULL, y = NULL, z = NULL)
rgl.light(theta = -0, phi = 0, viewpoint.rel = TRUE,  diffuse = "gray20", specular = "gray25", ambient = "gray80", x = NULL, y = NULL, z = NULL)
sapply(1:NROW(spheres), function(i) 
  drawSphere(spheres$x[i], spheres$y[i], spheres$z[i], r=1, lats = 400, longs = 400, color=spheres$color[i]))

spheres3d function, Higher numbers give a smoother shape. smooth. If TRUE, smooth interpolation of normals is used; if FALSE, a faceted ellipsoid will be displayed. Stack Overflow Public questions and answers; Teams Private questions and answers for your team; Enterprise Private self-hosted questions and answers for your enterprise; Talent Hire technical talent

[PDF] Package 'rgl', #RGL is a 3D graphics package that produces a real-time interactive 3D plot. #It allows to interactively rotate, #It's possible to draw spheres using the functions rgl.spheres() or spheres3d():. # spheres3d(x, y = NULL, xz <- expand.grid( x = x​.pred, z = z.pred) add light, smooth surface change x-axis limits. plotrgl(new  This document describes how to embed rgl scenes in HTML documents and use embedded Javascript to control a WebGL display in an HTML document. For more general information about rgl, see rgl Overview. We assume that the HTML document is produced from R markdown source using knitr or rmarkdown. This format mixes text with Markdown markup with

Here is my approach using persp3d.function()

sphere.f <- function(x0 = 0, y0 = 0, z0 = 0, r = 1, n = 101, ...){
  f <- function(s, t) cbind(r * cos(s) * cos(t) + x0,
                            r * sin(s) * cos(t) + y0, 
                            r * sin(t) + z0)
  persp3d(f, slim = c(0, pi), tlim = c(0, 2*pi), n = n, add = T, ...)
}

sphere.f(col = rainbow)

Alex Laier, lightid <- spheres3d(1,1,1,alpha=0) for (a in seq(-pi, pi, length.out=100)) { save <- par3d(skipRedraw=TRUE) clear3d(type = "lights") rgl.pop(id  With 260.99 version it's like another game. Smooth and beautiful. Choose this version because I remember that it was good in 2010. With this driver I've got same stable game with all new armors etc.

[PDF] Package 'rgl', How to increase smoothness of spheres3d in rgl. When I use rgl::spheres3d(), the rendered spheres have clunky facetted edges. spheres = data.frame(x = c(1,2  There are two ways to embed an rgl scene in the document. The recommended one is to call rglwidget to produce a “widget” which can be embedded into your document by printing it. The older method is described in the Legacy WebGL Methods document. It is likely to be supported for some time, but is not recommended for new projects, as the widget method is easier for me to maintain.

[PDF] Package 'rgl', This has the effect of making the surface of the object appear smooth rather than faceted when rendered. Usage. addNormals(x, ) Arguments x. 3D round solids do not display as a smooth surface in AutoCAD. They display as a series of edges. How to fix this? System variable FACETRES is set too small or a value Increase the value of FACETRES. The maximum value is 10

Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. How to increase smoothness of spheres3d in rgl. 4

Comments
  • This is excellent - good job. At n=101, the ridge defect around the equator is still there, but a good compromise between speed and quality. With n=201, its already hard to see. At n=301, barely discernible and still acceptably fast.
  • Thanks for giving me the correct answer vote. Would love to get a bronze badge in rgl, but at this rate it will take about 10 years.
  • Adding normals makes it look even better. You can do this by adding sphere$normals <- sphere$vb for a sphere, or more generally shape <- addNormals(shape).
  • I like the simplicity of this approach. And it can be improved by using dodecahedron3d() rather than cube3d(). Unfortunately, it does not work for high resolution spheres. If I increase depth above 6 I tend to get memory allocation errors. That said, dodecahedron3d at depth 6 looks pretty passable, if somewhat slow to process
  • Further to my last comment, adding @user2554330 's suggestion of adding normals to icosahedron3d() subdivided at depth 6, makes some pretty nice looking spheres
  • Yes, drawing your own sphere is the way to go. One possible improvement if you want just one colour is that you can draw just one sphere, and reuse it as a 3d sprite. That saves memory, which probably doesn't matter in R, but will make a noticeable difference in file size if you export the scene using rglwidget().
  • I would try downloading the source, editing the line mentioned above and the DESCRIPTION file (to set yourself to be the maintainer), and upload it up via ftp to win-builder.r-project.org
  • This makes some very nice smooth looking spheres, and is significantly faster to process than my qmesh3d based function. The one thing holding me back from accepting this answer is that the spheres have defects around the poles, where there are gaps in the surface, and also a slight ridge at the equator where the two hemispheres don't quite match up. Do you have any ideas about how to fix these issues?
  • @dww; Unfortunately it seems impossible. There some methods to express sphere with two variables. But low or high density area and/or duplicated points arise in any way.