Index

Luxor.betweenFunction
between(p1::Point3D, p2::Point3D, x=0.5)
between((p1::Point3D, p2::Point3D), x=0.5)

Find a point on a line between two 3D points. If x is 0.5, the returned point should be halfway between them.

source
Luxor.distanceMethod
distance(p1::Point3D, p2::Point3D)

Return the distance between two points.

source
Luxor.drawpathMethod
drawpath(path::Path, k::Real, anchor::Point3D;
    about=Point3D(0., 0., 0.),
    rotation::Rotation=RotXYZ(0, 0, 0),
    steps=20, # used when approximating Bezier curve segments
    action=:none,
    startnewpath=true,
    pathlength = 0.0)

Draw a Luxor Path object on a 2D plane, starting at anchor with rotation about about.

source
Luxor.midpointMethod
midpoint(pt1::Point3D, pt2::Point3D)

Find the midpoint between two points. See also between().

source
Thebes.carpetFunction
carpet(n; kind=:circular)

Draw a circular carpet centered at the origin, using current Luxor parameters.

If kind is not :circular, the carpet will be a square.

Points that can't be rendered are not included in the final shape.

source
Thebes.drawcubeFunction
drawcube(n=10, action=:stroke)

Draw a cube. drawcube(1) draws a wireframe unit cube.

source
Thebes.helloworldMethod
helloworld()

Reset all the things. The equivalent of typing:

eyepoint(100, 100, 100)
centerpoint(0, 0, 0)
uppoint(0, 0, 10)
perspective(0)
source
Thebes.hiddensurfaceMethod
hiddensurface(o::Object)

Given an object o, sort the faces in o.faces, then draw filled grey polygons for each face.

source
Thebes.import_off_fileMethod
import_off_file(fname)

Import a file in OFF (Object File Format).

Returns a Tuple - vertices, and faces. Vertices is a vector of [x, y, z], and faces a vector of vectors of vertex numbers.

off_file = raw"
    OFF
    8 6 0
    -0.500000 -0.500000 0.500000
    0.500000 -0.500000 0.500000
    -0.500000 0.500000 0.500000
    0.500000 0.500000 0.500000
    -0.500000 0.500000 -0.500000
    0.500000 0.500000 -0.500000
    -0.500000 -0.500000 -0.500000
    0.500000 -0.500000 -0.500000
    4 0 1 3 2
    4 2 3 5 4
    4 4 5 7 6
    4 6 7 1 0
    4 1 7 5 3
    4 6 0 2 4
"

f = open("/tmp/cube.off", "w") do f
    write(f, off_file)    
end

@draw begin
    o = make(import_off_file("/tmp/cube.off"))
    scaleby!(o, 100)
    pin(o)
end
source
Thebes.makeFunction
make(primitive, name="unnamed")

primitive contains two arrays, an array of 3D points, and an array of faces, where each face is a list of vertex numbers.

Returns a Object.

Example

make(Cube, "cube")

returns an Object object containing an array of vertices, an array of faces, and an array of labels.

@draw begin
    helloworld()
    tol = 0.01
    a = []
    sethue("black")
    for t in -2pi:tol:2pi
        push!(a, Point3D((50 + cos(5t)) * cos(3t), (50 + cos(5t)) * sin(2t), sin(5t)))
    end
    Knot = make((a, []), "knot")
    pin(Knot, gfunction=(args...) -> begin
        for verts in args[1].vertices
            pin(verts)
        end
    end)
end

The default gfunction expects faces - if there aren't any, use a gfunction that draws vertices.

source
Thebes.moveby!Method
moveby!(o::Object, x, y, z)
moveby!(o::Object, pt::Point3D)

Set the position of object to Point3D(x, y, z).

source
Thebes.moveby!Method
moveby!(ptlist::Point3D, x, y, z)
moveby!(ptlist::Point3D, pt::Point3D)

Move all points in the list by a vector.

source
Thebes.movebyMethod
moveby(o::Object, x, y, z)
moveby(o::Object, pt::Point3D)

Set the position of a copy of the object to Point3D(x, y, z).

source
Thebes.movebyMethod
moveby(pt::Point3D, d::Point3D)

Return a new point that's the result of moving a point pt by a vector d.

source
Thebes.newprojectionFunction

newprojection(ipos::Point3D, center::Point3D, up::Point3D, perspective=0.0)

Define a new Projection:

  • ipos is the eye position
  • center is the 3D point to appear in the center of the 2D image
  • up is a point that is to appear vertically above the center

If perspective is 0.0 (the default) the projection is parallel. Otherwise it's a vague magnification factor for perspective projections.

The three vectors U, V, W, and the three scalar products, ue, ve, and we:

  • U is at right angles to line of sight w, and to t-e, so it corresponds to

the x axis of the 2D image

  • V is at right angles to u and to the line of sight, so it's the y axis of the

2D image

  • W is the line of sight

  • we is the projection of the eye position onto w

  • ue is the projection of the eye position onto that x-axis

  • ve is the projection of the eye position onto that y axis

source
Thebes.objecttopolyMethod
objecttopoly(o::Object)

Return a tuple:

  • an array of 2D points representing the vertices of o

  • an array of 2D polygons representing the faces of o

Example

This example draws the faces of a cube in colors, and marks the vertices in black.

using Luxor, Thebes

@draw begin
    helloworld()
    o = make(Cube)
    scaleby!(o, 100, 100, 100)
    vs, fs = objecttopoly(o)
    setopacity(0.4)
    sethue("black")
    for face in fs
        randomhue()
        poly(face, :fill)
    end
    sethue("black")
    circle.(vs, 3, :fill)
end
source
Thebes.pinMethod
pin(o::Object;
    gfunction=(o) -> hiddensurface(o))

Draw a rendering of an object.

The default rendering function is hiddensurface().

You can also use the built-in wireframe() rendering function.

Examples

@draw begin
    o = make(Cube)
    axes3D(200)
    scaleby!(o, 200, 200, 200)
    eyepoint(250, 270, 300)
    pin(o) # use an attempted hiddensurface rendering

    o = make(Tetrahedron)
    axes3D(200)
    scaleby!(o, 200, 200, 200)
    eyepoint(250, 270, 300)
    pin(o, gfunction=wireframe) # use a wireframe rendering
end

More help

You could write your own rendering function to draw objects.

function a_rendering_function(o::Object)
   if !isempty(o.faces)
       sortfaces!(o)
       @layer begin
           for (n, face) in enumerate(o.faces)
               @layer begin
                   vertices = o.vertices[face]
                   sn = surfacenormal(vertices)
                   ang = anglebetweenvectors(sn, eyepoint())
                   setgrey(rescale(ang, 0, π, 1, 0))
                   pin(vertices, gfunction = (p3, p2) ->
                    begin
                       poly(p2, :fill)
                       sethue("white")
                       poly(p2, :stroke, close=true)
                    end)
               end
           end
       end
   end
end
source
Thebes.pinMethod
pin(p3_1::Point3D, p3_2::Point3D;
    gfunction = ((p3_1, p3_2), (p2_1, p2_2)) ->
        line(p2_1, p2_2, :stroke))

Draw two 3D points.

The default action is to draw a line between two points.

The gfunction can access the 3D points as the first argument, the two 2D points in the second argument.

pin(p, Point3D(50cos(θ), 50sin(θ), p.z),
    gfunction = (p3s, p2s) -> begin
        line(p2s..., :stroke)
    end)

Returns the two 2D points.

source
Thebes.pinMethod
pin(pt::Point3D;
    gfunction = (p3, p2) -> circle(p2, 1, :stroke))

Draw a single 3D point on the current Luxor drawing.

The default graphic is a circle. You can define others using a custom gfunction, which takes two arguments: the 3D point and its 2D counterpoint.

For example, this draws a circle whose radius is larger if the point is nearer to the eye.

pin(p, gfunction = (p3, p2) -> begin
        d = distance(p3, eyepoint())
        circle(p2, rescale(d, 0, 300, 20, 5), :fill)
    end
    )

Returns the 2D point.

source
Thebes.pinMethod
pin(p3list::Array{Point3D, 1};
    gfunction = (p3list, p2list) ->
        poly(p2list, :stroke, close=true))

Draw an array of 3D points.

The default action is to draw a polygon through all the points.

The gfunction can access the 3D points as the first argument, the two 2D points in the second argument.

helix = [Point3D(100cos(θ), 100sin(θ), 20θ) for θ in 0:π/12:4π]
a_box = pin(helix, gfunction =
    (p3list, p2list) -> prettypoly(p2list, :stroke)
    )

Returns the list of 2D points.

source
Thebes.pointsperpendicularFunction
pointsperpendicular(p1::Point3D, p2::Point3D, radius, angles = [0, π])

Find points perpendicular to a line joining p1 and p2. Points are radius units away from the line.

source
Thebes.projectMethod

project(P::Point3D)

Project a 3D point onto a 2D surface, as defined by the current projection.

TODO Currently this returns 'nothing' if the point is behind the eyepoint. This makes handling the conversion a bit harder, though, since the function now returns either a 2D Luxor point or nothing.

using Thebes, Luxor

@svg begin
    eyepoint(Point3D(250, 250, 100))
    centerpoint(Point3D(0, 0, 0))
    uppoint(Point3D(0, 0, 10))
    sethue("grey50")
    carpet(300)
    axes3D(100)
    sethue("red")
    for i in 1:30
        randpoint3D = Point3D(rand(0.0:150, 3)...)
        sethue("red")
        pt1 = pin(randpoint3D)
        if pt1 != nothing
            circle(pt1, 5, :fill)
        end
    end
end
source
Thebes.rotateXMethod
rotateX(pt3D::Point3D, rad)

Return a new point resulting from rotating the point around the x axis by an angle in radians.

Rotations are anticlockwise when looking along axis from 0 to +axis.

source
Thebes.rotateYMethod
rotateY(pt3D::Point3D, rad)

Return a new point resulting from rotating the point around the y axis by an angle in radians.

Rotations are anticlockwise when looking along axis from 0 to +axis.

source
Thebes.rotateZMethod
rotateZ(pt3D::Point3D, rad)

Return a new point resulting from rotating the point around the z axis by an angle in radians.

source
Thebes.rotateby!Method
rotateby!(o::Object, r::Rotation)
rotateby!(o::Object, angleX, angleY, angleZ)

Rotate an object through rotation r, or around the x, y, and/or z axis by angleX, angleY, angleZ.

source
Thebes.rotateby!Method
rotateby!(o::Object, pt::Point3D, angleX, angleY, angleZ)
rotateby!(o::Object, pt::Point3D, r::Rotation=RotXYZ(0, 0, 0))

Rotate an object around a point by rotation r, or angleX, angleY, angleZ.

source
Thebes.rotateby!Method
rotateby!(ptlist::Array{Point3D, 1}, angleX, angleY, angleZ)

Modify a list of points by rotating each one around the x, y, and z axes by angleX, angleY, angleZ.

source
Thebes.rotateby!Method
rotateby!(ptlist::Array{Point3D, 1}, existingpt::Point3D, angleX, angleY, angleZ)
rotateby!(ptlist::Array{Point3D, 1}, existingpt::Point3D, r::Rotation)
rotateby!(ptlist::Array{Point3D, 1}, r::Rotation=RotXYZ{Float64})

Rotate each point in the list by rotation (or angleX, angleY, angleZ) around another point (or origin).

source
Thebes.rotatebyMethod
rotateby(o::Object, angleX, angleY, angleZ)

Rotate a copy of the object by angleX, angleY, angleZ.

source
Thebes.rotatebyMethod
rotateby(o::Object, pt::Point3D, angleX, angleY, angleZ)
rotateby(o::Object, pt::Point3D, r::Rotation=RotXYZ(0, 0, 0))

Rotate a copy of the object around a point by rotation r, or angleX, angleY, angleZ.

source
Thebes.rotatebyMethod
rotateby(pt::Point3D, angleX, angleY, angleZ)
rotateby(ptlist::Array{Point3D, 1}, angleX, angleY, angleZ)
rotateby(point::Point3D, r::Rotation)
rotateby(ptlist::Array{Point3D, 1}, r::Rotation)

Return a new point/list of points resulting from rotating around the x, y, and z axes by angleX, angleY, angleZ.

The Z rotation is first, then the Y, then the X.

A 3×3 rotation matrix parameterized by the "Tait-Bryant" XYZ Euler angle convention, consisting of first a rotation about the Z axis by theta3, followed by a rotation about the Y axis by theta2, and finally a rotation about the X axis by theta1.

source
Thebes.rotatebyMethod
rotateby(point::Point3D, about::Point3D, angleX, angleY, angleZ)
rotateby(point::Point3D, about::Point3D, r::Rotation)
rotateby(ptlist::Array{Point3D, 1}, about::Point3D, r::Rotation)
source
Thebes.scaleby!Method
scaleby!(ptlist::Array{Point3D, 1}, x, y, z)

Scales a list of points by multiplying by x in X, y in Y, z in Z.

source
Thebes.sortfaces!Method
sortfaces!(o::Object;
    eyepoint::Point3D=eyepoint())

Find the averages of the z values of the faces in Object, and sort the faces of o so that the faces are in order of nearest (highest) z relative to eyepoint...

or something like that ? not sure how this works

source
Thebes.sphericaltocartesianMethod
sphericaltocartesian(ρ, θ, ϕ)

Return Point3D(x, y, z) corresponding to (ρ, θ, ϕ):

  • ρ is the distance from the origin (ie radius)

  • θ is the azimuthal angle (the longitude) 0 is +x, π is -x, 2π is +x

  • ϕ is the polar angle (the latitude) 0 is North Pole, π is South Pole

There are two major conventions for spherical coordinate notation.

In physics books:

(ρ, θ, φ) gives the radial distance, polar angle (latitude), and azimuthal angle (longitude)

In mathematics books:

(ρ, θ , φ ) gives the radial distance, azimuthal angle (longitude), and polar angle (latitude)

So we're using the mathematics one here.

source
Thebes.text3DMethod
 text3D(str, anchor::Point3D;
    halign=:left,
    valign=:baseline,
    about=Point3D(0., 0., 0.),
    rotation::Rotation=RotXYZ(0, 0, 0))

Draw text at point pt, lying in the plane of the x axis. Angles in rotation rotate the text about the about point, defaulting to Point3D(0, 0, 0).

Uses Luxor's fontface() and fontsize() settings.

Specify rotations using functions from Rotations.jl, such as:

  • RotX(a)
  • RotZ(a)
  • RotXZ(a1, a2)
  • RotXYZ(a1, a2, a3)
source
Thebes.uppointMethod
uppoint(pt::Point3D)

Specify the "up" direction for the world: a line from the centerpoint to the uppoint defines the up direction.

source
Thebes.uppointMethod
uppoint()
uppoint(pt::Point3D)

The "up" direction for the world: a line from the centerpoint to the uppoint defines the up direction.

source
Thebes.wireframeMethod
wireframe(o::Object)

Given an object o, sort the faces in o.faces, then draw grey stroked polygons for each face.

source