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.

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

Return the distance between two points.

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

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

Thebes.axes3DFunction
axes3D(n=100)

Draw labelled 3D axes at (0, 0, 0) with length n.

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.

Thebes.dotproduct3DMethod
dotproduct3D(a::Point3D, b::Point3D)

Finds the dot product of a and b

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)
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...) -> poly(args[1], :stroke))
end

The default gfunction expects faces - if there aren't any, use a gfunction that draws vertices.
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

Thebes.objecttopolyMethod
objecttopoly(m::Object)

Return a list of 2D points representing the 3D Object in m.

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.

Thebes.pinMethod
pin(m::Object;
    gfunction = (v, f, l; kwargs... ) -> simplegfunction(v, f, l; kwargs...))

Draw an object, calling a gfunction, the default is simplegfunction().

To define and change the default gfunction:

function mygfunction(vertices, faces, labels; action=:fill)
    setlinejoin("bevel")
    if !isempty(faces)
        @layer begin
            for (n, p) in enumerate(faces)
                 @layer begin
                     isodd(n) ? sethue("grey30") : sethue("grey90")
                     setopacity(0.5)
                     poly(p, action)
                 end
                 sethue("black")
                 setline(0.5)
                 poly(p, :stroke, close=true)
             end
        end
    end
end

@svg begin
    helloworld()
    object = make(Cube)
    setscale!(object, 100, 100, 100)
    rotateby!(object, object.vertices[1], rand(), rand(), rand())
    sortfaces!(object)
    pin(object, gfunction = mygfunction)
end
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.

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.

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, 1))
    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
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.

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

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

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

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

Thebes.rotateby!Method
rotateby!(m::Object, angleX, angleY, angleZ)

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

Thebes.rotateby!Method
rotateby!(m::Object, pt::Point3D, angleX, angleY, angleZ)

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

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

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

Thebes.rotatebyMethod
rotateby(m::Object, pt::Point3D, angleX, angleY, angleZ)

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

Thebes.rotatebyMethod
rotateby(pt::Point3D, angleX, angleY, angleZ)

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

Thebes.rotatebyMethod
rotateby(newpt::Point3D, existingpt::Point3D, angleX, angleY, angleZ)

Return a new point resulting from rotating the point by angleX, angleY, angleZ around another point.

Thebes.setposition!Method
setposition!(ptlist::Point3D, pt::Point3D)

Move points by a vector..

Thebes.setposition!Method
setposition!(m::Object, x, y, z)
setposition!(m::Object, pt::Point3D)

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

Thebes.setpositionMethod
setposition(m::Object, x, y, z)
setposition(m::Object, pt::Point3D)

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

Thebes.simplegfunctionMethod
simplegfunction(vertices, faces, labels; action=:stroke)

In a Luxor drawing, draw the 2D vertices and faces, using alternating grey shades.

Thebes.sortfaces!Method
sortfaces!(m::Object;
    eyepoint::Point3D=Point3D(0, 0, 0))

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

or something like that ? not sure how this works

Thebes.text3DMethod
text3D(str, pt::Point3D;
    halign=:left,
    valign=:baseline,
    rotation = (0, 0, 0)))

Draw text at point pt, lying in the plane of the x axis. Angles in rotation can rotate the text away from the x plane around the x, y, and z axes.

Uses current fontface() and fontsize() settings.