Proposal for a 1-point perspective assistant tool

This proposal emerges from a previous thread, discussing how to draw square and cubes in perspectives with krita. After many contributions and long discussions, this previous thread leads to the necessity of a formal feature proposal.

The main idea is to revisit the current “perspective” assistant tool and to propose a new user interface for it. Most of its code development could reuse existing materials and this proposition could be interpreted as an evolution of the krita assistant tools. A short and clear summary of the geometrical construction of 1-point perspective could be found in the following 12’ very nice video:

For reading the present proposal, very few mathematics are required, only 2D basic geometric operations, such as line intersections. Moreover, there is absolutely no 3D concepts. Here, 3D effects are created in the human brain, no more. Let us turn to the proposed user interface. We identified two stages for creating a “1-point perspective” assistant tool, plus and optional third stage for its customization. Next, the proposal studies a possible interface variant and a combination of this tool with the transform tool. It closes with a short discussion and future works.

1.1] Step 1: vanishing point and horizon line

During this stage, the user has to provide three points, freely chosen anywhere in the bi-dimensional plane, and denoted by VP, A1 and A2. By convention, we assume that A1 has a lower abscissa than A2 (i.e. A1 is at the left of A2). The first user’s click defines VP, the vanishing point. Then, when the cursor moves, a line from VP to the cursor position appears. At the second click, we get either A1 or A2, depending upon the future position of A2.

Without loss of generality, and for simplicity, assume that the user chooses A1 for the present explanations. After the second click, a set of lines, appear, starting from VP, and equi-distributed between A1 and A2, which is defined by the cursor position. There are N+1 of such lines and N is a strictly positive integer that could be customized in the “tool option” panel. The default value for N is 8. Simultaneously, a line, passing by VP and parallel to the line (A1,A2), appears: this is the horizon line. Note that the horizon line is not necessarily horizontal: you could think about a boat on the sea. Note also that this interface differs from the already existing “vanishing point” assistant tool: the points here are equi-distributed along the segment [A1,A2] while the present assistant tool bases upon a equi-distribution of angles around the vanishing point, similar to sunbeams. This difference is here of major importance. At the third user’s click, the cursor position freezes the location of A2.

1.2] Step 2: tiles and depth reduction

Here comes the major contribution of this proposal. During stage 2, the user has to provide an additional line, parallel to (A1,A2), and that intersect the two segments [VP,A1] and [VP,A2] at B1 and B2, respectively. The two intersections B1 and B2 express as:

    B1 = VP + theta*vector(VP,A1)
    B2 = VP + theta*vector(VP,A2)

where theta is a real number. Observe that theta belongs in the open interval ]0,1[ if and only if the cursor position belongs inside the banded region delimited by the horizon line and the line (A1,A2). This is a major assumption for continuing the computations.

On the previous image, the annotations in magenta do not appear to the user’s during the interface: only the grey lines should be shown. These annotations are shown here for the purpose of the geometrical construction. First, let us consider the diagonal line (A1,B2). It intersects the horizon line at DVP, the diagonal vanishing point. It also intersect the N+1 lines coming from VP and going to the equi-distributed points in the segment [A1,A2]. We then obtain N+1 intersection points along the diagonal segment [A1,B2]. Next, we draw N+1 segments passing from these intersection points and parallel to (A1,A2): we obtain the tile together with the size reduction. During the cursor displacements, the tile are dynamically updated, as a preview, and when the user clicks, the composition is frozen. After that, the value of theta could be modified by using the square-shaped handles at B1 or B2. Optionally, we could also consider another equivalent handle at DVP, for convenience.

Observe that the cases theta=0 and theta=1 correspond to a degeneracy: the “diagonal line” is no more diagonal and the intersections are no more well-defined. For a practical implementation, we first compute a guess, denoted as theta’, by using the previous formula. We then bound strictly this guess value in the interval ]0,1[ as:

    theta = min(0.99, max(0.01, theta'))

By this way, the cursor could go anywhere in the bi-dimensional plane, and theta is initialized as theta=0.5. When the cursor is outside the banded region, the value of theta remains unchanged.

1.3] More goodies: walls, ceiling, back and front

At this stage, the tiles are well defined: the user could still adjust the position of VP, A1, A2 and B1 or B2, by using the handles. In addition to the number N of tile density, the “tool option” panel provides five independent boolean flags for showing the left and right walls, the celing, the front and the back. In the 1-point perspective, the front and the back are in frontal views, and do not present any size reduction: the tile have just to fit along the [A1,A2] and [B1,B2] segments.

Next, the left and right wall are elaborated: the tiles also have to fit along the boundaries with the floor, back and front walls. Finally, the ceiling could be added in the same way.

The “tool option” panel could looks like:

  number of tiles: 8
  show floor     : [x]
       ceiling   : [ ]
       left wall : [ ]
       right wall: [ ]
       back      : [ ]
       front     : [ ]

Finally, when drawing with a brush, a “snap to assistant” boolean flag appears in the tool option panel:

  [x] snap to assistant

1.4] Alternative definition based on the first tile

The previous user’s interface could be called the Rubik’s cube one, since it is convenient for drawing such a composition, or similarly a scene in a room. Another popular composition is the railway one, or similarly, the tree-lined road. This new interface solves in an elegant way the railway problem, as presented in the krita manual. In that case, it is more convenient to define instead, at step 2, the theta coefficient via the depth of the first tile. Now, the two handle are located at B1’ and B2’, as shown on the figure:

The intersection of the line passing via the cursor and parallel to (A1,A2) intersects the two segments [VP,A1] and [VP, A2] at B1’ and B2’, respectively. It also intersects the segment between VP and the first equi-spaced point between A1 and A2 at a point C. Then, the diagonal is the line (A1,C) and finally, B1, B2 and the theta coefficient are obtained as in the previous case. Note that, by increasing the value of N, the number of tiles by sides, the B1 and B2 points go closer to VP: this is convenient for a strait railway or tree-lined road.

The “tool option” panel could have an additional scrolling menu:

  tile adjustment: at last tile (default)
                   at first tile

1.5] Combining with the transform tool

Tiles are convenient as guides for placing some patterns. Patterns can be placed thanks to the “transform” tool combined with its “perspective” option.

The previous image was produced by using three clone layers of this photography of my wood mannequin, together with a transformation mask. The aspect ratio of the original mannequin image was 1:2. Observe how the tiles are used as guides for a careful placement that conserves this aspect ratio. Note also that, for the two clones staying in a vertical position, the positions of the eyes are chosen close to the horizon line.

Discussion and conclusion

Krita already provides some closely related assistant tools:

While they are useful for maintaining the user’s brush along some directions, none of these tools address the fundamental problems in perspective:

  • reducing lengths in depth
  • reporting lengths from one direction to the other

The current proposal is an attempt to fill this gap, at least for 1-point perspective. In the future, if krita’s users and developers are interested by, I will prepare a proposal for a “2-point perspective” tool (i.e. for oblique perspective). Such a perspective is very common in practice, about 50% of the compositions involving perspective. I will also consider its possible extension to 3-point perspective (i.e. panoramic views) and nonlinear (fisheyes, etc) cases.

As a final remark, I anticipate some classical questions:

  • Why not using blender and then importing in krita ?
    -> Blender is 3D, suitable for complex scenes, see e.g. this, while I consider here only classical 2D scenes with an evolution of the krita assistant tools: 3D effects will be created in the human brain.
  • Do you known if photoshop already has something similar ?
    -> I don’t use photoshop, I cannot answer this.
1 Like

The Problem I have with the current assistant tool is that it is very fiddly and inaccurate to set up different perspectives. The vanishing points don’t snap do each other, you have no indicators for positions and angles and sometimes its hard to interact with them without accidentally pacing new vanishing points. This is especial frustrating when you try to do technical drawings where you have to be very accurate. I know how all the perspectives work and how to construct them but somehow I still find it faster to make it with straight edge and compass on a piece of paper instead of using Krita. Especially when I want the grid to appear like it was viewed though a lens with specific focal length. I can imagine that beginners will find it even more difficult.

If I were to remake the perspective assists I would rework it like this:

  • Let the user chose from one of the common perspectives (one, two, three, fish-eye)
  • maybe have some nice presets already to chose from, like isometric
  • give them an input field for the focal length of the lens with some sane default (like 50mm)
  • give them input fields for the “camera” positions x, y, z axis (probably with some sliders instead of raw numbers
  • give them an input field for the “camera” rotation on x, y, z axis (again sliders)
  • input field for how many guide-lines to show
  • check box for optionally showing “walls” and a “roof”
  • imputs positions for said walls.
  • an input for where the horizon should end I guess?

Krita then adjust the Perspective Grid on the canvas accordingly.

This would probably already fit 90% of use cases for perspective grids in Krita. If you want to lay out complete scenes to create you own reference material, I’d recommend using something like blender, that’s what I just started doing for the concept stage of an artwork.


Thanks @Takiro for your comments: I fully agree with you, except for the two 3D-related items:

From @Takiro:
- give them input fields for the “camera” positions x, y, z axis (probably with some sliders instead of raw numbers
- give them an input field for the “camera” rotation on x, y, z axis (again sliders)

Krita is a 2D drawing tool: you draw on 2D, krita computes in 2D and your brain interprets the result in 3D.
As your sheet of paper and your tablet, krita shoud remain 2D. Blender is a 3D modeler: it computes in 3D and projects a 2D scene on your screen, you can interact with the camera. Trying to include in krita some 3D concepts, such as camera movements, is not a good idea, in my opinion.
For all the others points, I agree with you, @Takiro.

Clearly, good and experimented artists need neither a krita “assistant tool” nor “blender” to draw a correct complex scene: such artists are able to eyeball all without any perspective error. But an efficient krita assistant could lead them to work faster, while importing from blender could slow down. For less experimented artists, an efficient assistant could be useful for avoiding mistakes, and would open to everybody the world of perspective.

So, between these two extremes: eyeballing perspective and using 3D modelers as blender, there is still a large room for developing an improved perspective assistant tool in krita.

However you turn it, what we artists do all the time in our works is projecting three dimensional space onto a two dimensional surface. Sure our workspace is a plane but that doesn’t make the objects we try to represent on that plane any less three dimensional, just as a cube does not become flat just because you take a photo of it, the photograph is of course flat so is our artwork. In Blender you 3D environment is also just projected onto a 2D plane, your screen. When we change the perspective we effectively change the position of “the camera”.

If you don’t like the idea of a camera, imagine it as the head of the observing person and the different axes are the persons location and height as well as its head’s rotation and tilt. That’s pretty much how it’s described in all the books about perspective I read. I used the word camera because it’s easy to understand for anyone who ever tried to take reference photos of objects from different angles and so changing the perspective. When I look at a cube spot on and slightly from the top (change my head’s position on the z Axis) I get one point perspective. When I change my position by walking around the cube to look directly at an edge (changing x and y axis as well as rotation) I get two points and when I change my z position even more by standing up and than look down on the cube I have three point perspective until I’m directly above it and have one point again.

Yes, @Takiro, there are two distinct families of softwares:

  • drawing tools, such as krita, gimp, mypaint or inskape. The assistant tools provides some 2D handles. When you interact with them, you change some (x,y) data in its internal 2D data structure.
  • modellers, such as blender, when you interact with handles, you change some (x,y,z) its 3D internal data structure.

To my opinion, its sane to clearly conserve this difference between these two families of softares: krita should not try to become 3D in the future.

For instance, in the last previous image, with the mannequin, I cannot rotate the scene: krita do not have any 3D description of the mannequin, its just a 2D image with a linear 2D deformation applied on it. The resulting 3D effect is just in our brain… Similarly, there is no cubes, in this scene, just 2D lines and flat polygons. With drawing tools, the 3D effect is in your brain… as when you draw on a sheet paper.

I don’t get you. Having a perspective grid that is easily “rotatable” doesn’t make Krita a 3D program just as redrawing my grid on a piece of paper to change the perspective makes it a 3D model. You still draw in 2D it’s just that the grid is easy to adjust which is solely a guide, no one expects Kirta to let you 3D model something, that’s not the use of the perspective assist tools.

Our real world is 3D and “moving around” to get a different perspective is just the natural way that everyone can understand. However if you don’t like that idea, then think about rotating and moving the perspective grid since from a math perspective it does not matter if you move the observer around around an object or just rotate the object and the world around an observer. This is what I learned when I programmed my own 3D engine as an exercise when I was young.

Otherwise I see not much usability improvement over the current assistance tools and the vanishing point system that already exists. A rotatable grid would give you all the perspectives in one tool.

From @Takiro :
Having a perspective grid that is easily “rotatable” doesn’t make Krita a 3D program

Oh, sorry @Takiro ! Its a misunderstanding ! I’ve understand you want that krita becomes blender :wink:
It’s so difficult to explain this by mails…

If I understand you well now (and please, confirm it !), you propose to change the way we are interacting with such a future 1-point perspective assistant tool (let us keep 2-point and more for later). So you are in front of your cube. How many degrees of freedom has your interaction system, defined by our set of handles ? Which one are them ? Please could you be more precise, could you propose some pictures showing them ?

With my previous proposition, the interaction system was defined by the handles: three points VP, A1 and A2 in 2D, so 6 degrees of freedom + theta for the back of the cube. Then, in total 7 independent degrees of freedom. For these two interaction systems to be equivalent, you should at least have the same number of degrees of freedom. Perhaps yours is more user-friendly, so let us study it in details!

Oh, no! As much as i like Blender that would be definitely to much x3. However some concept artist would probably love to place some primitive “3D-ish” objects in the grid and rotate them for trying out different compositions without having to re-sketch everything over and over (that’s what I do with blender).

But yes, i mostly want to just improve on the existing tools and how to interact with them and making it easier to set up the different perspectives. Whenever I use the assistant tools, usually for 3 point, I find it a hassle to set it up and then I think of blender where you just rotate the view around the horizontal axes, takes like a second or so and done.

I will make a mock-up of how I imagine it could work in Krita, when I find the time.

1 Like

By the way, to add more oil to the fire, here’s an old, but still relevant and in my opinion very good mockup by David Revoy (@deevad):

1 Like

Many thanks @tiar, for this link: after a first fast reading, is appears very interesting! I will read it again with details. Is would be nice to have @deevad 's opinion about how to define the user’s interaction.

This is an excellent write-up @pirogh (as well as @Takiro and @tiar for their contributions). :slightly_smiling_face: There are some really good and well-reasoned suggestions here.

I’ve also done my fair share of perspective drawing in Krita and I can agree that, while the Assistants Tool is quite helpful, it still leaves a lot to be desired in terms of accuracy and control.

In my experience, drawing a scene in perspective with Krita right now forces us to use multiple independent assistants at the same time. For example, I might set up a parallel ruler as a horizon line as well as a handful of individual vanishing point assistants (often, but not always, on the horizon line). This approach, which I think is the best approach with the current tools, has some major shortcomings:

  1. Because a perspective setup in Krita is composed of multiple independent assistants, coupled with the lack of ability to snap assistants to each other, means that creating common perspective setups is tedious and demands quite a bit of patience and knowledge from the user. Vanishing points aren’t “aware” of the horizon line nor can they easily be snapped to the horizon line, which makes setup annoying and error-prone.

  2. Krita’s current vanishing point assistants don’t help you create accurately foreshortened planes! Right now it’s quite easy to draw a foreshortened plane or box in 1-point perspective, but due to the fact that it doesn’t help you generate “tiles” it doesn’t do anything to help you subdivide space or place and scale objects appropriately. This issue can be mitigated by using a perspective assistant, which isn’t too unlike what you’re proposing here, but with some minor issues (strokes must start over the plane, “walls” pulled out of the plane don’t automatically conform to the same vanishing point as the “floor”, etc.)

  3. When using “Snap Brush to Assistants” with multiple assistants, Krita semi-regularly fails to snap to the desired assistant in my experience. In order to work around this, I have to constantly “juggle” which assistants are visible and which are hidden due to the fact that the brush doesn’t snap to hidden assistants. Because each assistant is independent, with no grouping or tree structure, this is pretty tedious!

  4. Sometimes a drawing with a variety of object rotations (image a bunch of boxes floating in space) or multiple compositions in one (for example, a comic book with different panels) can have multiple, unrelated perspective setups. Krita simply cannot handle this right now, due to problems with visibility and control related to having tons and tons of assistants in a single document. I think this situation demands some kind of grouping or tree structure for assistants.

  5. Right now the brush tool always snaps to the exact center of each assistant, but in traditional drawing, pencils, pens and brushes usually ride along the edge of things like rulers or ellipse guides. The difference here is pretty subtle when using a fine brush (like a pencil), but if you want to use a ruler assistant with a relatively large brush tip in a drawing with perspective, you’ll quickly run into perspective issues caused by the brush being centered on the ruler. (Maybe I should make an image that shows the problem.) Ideally, it would be possible, as easy, to have your brush snap to the center or either edge of a given assistant!

Anyway, that’s a big wall of text, I know. (I need an editor.) But I think this is a really important discussion so I wanted to share some of my thoughts and experiences. I’m also hoping to jump into improving Krita’s assistants after our animation workflow project has slowed down. ;D


2 posts were split to a new topic: How to link brush dab to perspective assitant plane