Skip to contents

painter_depth() computes depth values for use with the painter's algorithm. For parallel (orthographic or oblique) projections, depth is a dot product of the point with the projection direction vector derived from the plane and oblique parameters. painter_order() wraps painter_depth() and order() to return the integer indices that sort objects farthest-first (the draw order for the painter's algorithm). sort.Coord2D() and sort.Coord3D() wrap painter_order() to return the sorted object directly. sort.Coord2D() also handles Segment2D objects via inheritance.

Usage

painter_depth(x, ...)

# S3 method for class 'Coord2D'
painter_depth(x, ..., scale = 1, alpha = angle(45, "degrees"))

# S3 method for class 'Coord3D'
painter_depth(
  x,
  permutation = c("xyz", "xzy", "yxz", "yzx", "zyx", "zxy"),
  ...,
  plane = as_plane3d("xy-plane"),
  scale = 0,
  alpha = angle(45, "degrees"),
  roll = angle(0, "degrees")
)

# S3 method for class 'Segment2D'
painter_depth(x, ..., scale = 1, alpha = angle(45, "degrees"))

# S3 method for class 'Polygon2D'
painter_depth(x, ..., scale = 1, alpha = angle(45, "degrees"))

painter_order(x, ...)

# S3 method for class 'Coord2D'
painter_order(
  x,
  ...,
  decreasing = FALSE,
  scale = 1,
  alpha = angle(45, "degrees")
)

# S3 method for class 'Coord3D'
painter_order(
  x,
  permutation = c("xyz", "xzy", "yxz", "yzx", "zyx", "zxy"),
  ...,
  decreasing = FALSE,
  plane = as_plane3d("xy-plane"),
  scale = 0,
  alpha = angle(45, "degrees"),
  roll = angle(0, "degrees")
)

# S3 method for class 'Polygon2D'
painter_order(
  x,
  ...,
  decreasing = FALSE,
  scale = 1,
  alpha = angle(45, "degrees")
)

# S3 method for class 'Coord2D'
sort(x, decreasing = FALSE, ..., scale = 1, alpha = angle(45, "degrees"))

# S3 method for class 'Coord3D'
sort(
  x,
  decreasing = FALSE,
  ...,
  permutation = c("xyz", "xzy", "yxz", "yzx", "zyx", "zxy"),
  plane = as_plane3d("xy-plane"),
  scale = 0,
  alpha = angle(45, "degrees"),
  roll = angle(0, "degrees")
)

Arguments

x

Object to compute painter's depth/order for, or to sort.

...

Passed to as_plane3d() or as_angle() as needed.

scale

Oblique projection foreshortening scale factor. The 2D methods default to 1 since 0 yields zero depth for all Coord2D points (z is always 0), making depth-based ordering impossible. The Coord3D method defaults to 0 (orthographic projection, depth = z). A value of 0.5 is used by a “cabinet projection” while a value of 1.0 is used by a “cavalier projection”. All positive values produce the same ordering.

alpha

Oblique projection angle (the angle the off-axis direction is projected going off at). An angle() object or one coercible to one with as_angle(alpha, ...). Popular angles are 45 degrees, 60 degrees, and arctangent(2) degrees.

permutation

Either "xyz" (no permutation), "xzy" (permute y and z axes), "yxz" (permute x and y axes), "yzx" (x becomes z, y becomes x, z becomes y), "zxy" (x becomes y, y becomes z, z becomes x), "zyx" (permute x and z axes). This permutation is applied before the projection.

plane

A Plane3D class object representing the plane projected onto, or an object coercible to one using as_plane3d(plane, ...) such as "xy-plane", "xz-plane", or "yz-plane".

roll

Rotation of the in-plane coordinate frame around the plane normal after the azimuth/inclination alignment. An angle() object or one coercible to one with as_angle(roll, ...). Defaults to angle(0) (no roll), which preserves the azimuth/inclination convention.

decreasing

If TRUE sort/order closest first instead of farthest first.

Value

painter_order() returns an integer vector of indices.

sort.Coord2D() and sort.Coord3D() return a sorted object of the same class as x.

Examples

# Coord2D: oblique projection with scale = 1, alpha = 45 degrees
p <- as_coord2d(x = c(1, 2, 3), y = c(3, 1, 2))
painter_depth(p)
#> [1] -2.828427 -2.121320 -3.535534
painter_order(p)
#> [1] 3 1 2
sort(p)
#> <Coord2D[3]>
#>      x y w
#> [1,] 3 2 1
#> [2,] 1 3 1
#> [3,] 2 1 1

# Coord3D: orthographic projection onto xy-plane (depth = z)
p3 <- as_coord3d(x = 1:3, y = 1:3, z = c(3, 1, 2))
painter_depth(p3)
#> [1] 3 1 2
painter_order(p3)
#> [1] 2 3 1
sort(p3)
#> <Coord3D[3]>
#>      x y z w
#> [1,] 2 2 1 1
#> [2,] 3 3 2 1
#> [3,] 1 1 3 1

# Segment2D: depth/order at midpoints
p1 <- as_coord2d(x = c(0, 2), y = c(0, 0))
p2 <- as_coord2d(x = c(2, 2), y = c(0, 2))
s <- as_segment2d(p1, p2 = p2)
painter_depth(s)
#> [1] -0.7071068 -2.1213203
painter_order(s)
#> [1] 2 1
sort(s)
#> <Segment2D[2]>
#>      p1$x p1$y p2$x p2$y
#> [1,]    2    0    2    2
#> [2,]    0    0    2    0

# Polygon2D: depth/order of each edge
vertices <- as_coord2d(x = c(0, 0.5, 1, 0.5), y = c(0.5, 1, 0.5, 0))
poly <- as_polygon2d(vertices)
painter_depth(poly)
#> [1] -0.7071068 -1.0606602 -0.7071068 -0.3535534
painter_order(poly)
#> [1] 2 3 1 4