The method, in full

How the drills measure

Every formula, every threshold, and the evidence each one was set from. Published because a tool that claims to measure should be checkable, and because a number you cannot interrogate is just an opinion with a decimal point.

Generated from the engine itselfCannot drift from the product

In one paragraph

What actually happens when you press Measure

Your stroke is captured as a list of points with timestamps, then kept in two forms, because using the wrong one is a silent correctness bug rather than a crash. Shapes are fitted to a version resampled to uniform arc length; speed and tremor are measured on the raw timing. Fitting the raw points would make the fit density-weighted, so a slowly-drawn flat spot pulls the fitted centre toward itself and hides the very defect worth naming.

A shape is then fitted — a circle by the Taubin method, an ellipse by searching the rotation and solving the axes exactly at each one — and the deviations between your stroke and that fit become a vector of dimensionless numbers. Those numbers feed two independent things: a score, which reads them continuously, and a set of diagnostic rules, which read them through thresholds. Nothing is uploaded, and no model is involved at any point.

The score

One curve, and why it is that curve

Per quantity

score = 100 / (1 + (error / e50)^1.6)

Overall

0.75 × weighted mean + 0.25 × worst single quantity

e50 is the error that scores exactly 50, chosen per quantity from measured fixtures. The curve is smooth and monotone, so any real improvement registers, and asymptotic, so perfection stays out of reach. Differentiating it gives −25p per natural log of error, which with p = 1.6 means a 25% reduction in error is worth about +11.5 points. That is a design parameter rather than a hope: the second attempt has to move visibly or the loop does not teach anything.

The worst-quantity term is a quarter of the total on purpose. It makes the score hard to game by being excellent at one thing, and it keeps the number and the named fault pointing at the same problem.

The maximum is 99, not 100. Below roughly half a percent of radial error we are measuring capture noise rather than your hand, and a 100 would claim a precision we do not have.

Per drill

What each drill scores

Freehand circle

Measures your line, not your drawing
QuantityMeasured valuee50Weight
Roundnesscircle.radialRmsNorm0.0638%
Evennesscircle.worstArcDepth0.05521%
Steadinesscircle.wobbleNorm0.0317%
Closurecircle.closureNorm0.148%
Commitmenttiming.tracedNorm0.459%
One Gotiming.uncommittedNorm0.56%

Each is mapped through 100 / (1 + (e/e₅₀)^1.6), then combined as 75% the weighted average and 25% the single worst of them — so you cannot bank a beautiful curve to cover a circle that never closed. The top score is 99: below about half a percent of error we are measuring our own capture noise rather than your hand.

Straight line between two points

Measures your line, not your drawing
QuantityMeasured valuee50Weight
Aimline.lateralError0.05526%
Straightnessline.bowAbs0.04524%
Steadinessline.wobble0.01221%
Stoppingline.stopError0.088%
Startingline.startError0.086%
Commitmenttiming.uncommittedNorm0.859%
Single Passline.retraceNorm0.26%

Your stroke is measured against the two dots, never against a best-fit line through what you drew — fitting your own stroke would give a beautifully straight line drawn in the wrong direction a perfect score. Everything is divided by the distance between the dots, so the numbers mean the same thing on a phone and on a desktop.

Ellipse inside a plane

Measures your line, not your drawing
QuantityMeasured valuee50Weight
Degreeellipse.degreeErrorAbs1121%
Alignmentellipse.axisErrorAbs916%
Shapeellipse.unevenNorm0.0313%
Steadinessellipse.wobbleNorm0.02811%
Fillellipse.fillError0.210%
Placementellipse.centreOffsetNorm0.359%
Closureellipse.closureNorm0.166%
Tempoellipse.lapTempoError0.36%
One Gotiming.uncommittedNorm0.58%

Everything is measured in the ellipse’s own space: we fit the ellipse, then map your stroke through the inverse transform so it becomes a circle. An ellipse IS a circle under an affine transform, so all the roundness machinery applies unchanged — which is why "one end is pinched" can be stated at all.

Divide by eye

Measures your judgement, not your drawing
QuantityMeasured valuee50Weight
Accuracyproportion.rmsError0.07565%
Worst Markproportion.maxErrorAbs0.1135%

Every number here is a fraction of the bar it belongs to, never a pixel count. That is the whole reason this drill exists: a circle drawn with a finger on a phone is partly a measurement of the phone, but a tick costs nothing to place on any device, so what is left in the error is your judgement — and judgement is the part that carries over to paper.

Draw the other half

Measures your half against the given one
QuantityMeasured valuee50Weight
Widthsymmetry.meanAbs0.05536%
Biassymmetry.biasAbs0.04524%
Placementsymmetry.heightShiftAbs0.0516%
Steadinesssymmetry.driftGrowth0.0614%
Closingsymmetry.endpointNorm0.0510%

Weighted toward matching the width and toward the direction of your misses, because a consistent lean is the fault this exercise exists to expose and the one people cannot see in their own work.

A box in perspective

Measures whether your edges agree
QuantityMeasured valuee50Weight
Convergencebox.worstRmsDeg3.632%
Parallelsbox.parallelErrorDeg48%
Agreementbox.meanRmsDeg2.811%
Depthbox.separationError0.313%
Distortionbox.crowdingError0.59%
Lineworkbox.wobbleNorm0.02210%
Cornersbox.cornerGapNorm0.066%
Drawn Throughbox.missingEdges46%
Structurebox.familyImbalanceError0.256%

Nothing here is compared against a reference box, because there is no such thing as the correct box — there are only boxes whose edges agree with each other and boxes whose edges do not. Every number is a relationship inside your own drawing, which is why any box, at any angle, in any style, is measured the same way.

A cylinder in perspective

Measures whether your ends sit on the form
QuantityMeasured valuee50Weight
Squarenesscylinder.minorAxisErrorDeg931%
Recessioncylinder.degreeShiftError0.3520%
Joinscylinder.tangentMissNorm0.1417%
Tapercylinder.taperError0.3513%
Lineworkcylinder.sideBowNorm0.04511%
End Shapecylinder.endShapeError0.0358%

Weighted toward squareness and recession, because those are the two things that make a drawn cylinder read as a solid — the rest describe how tidily it was assembled.

Every threshold, and its evidence

When a fault is named

Each rule returns a severity between 0 and 1, ramped linearly from t — where the quantity starts to matter — to full, where it is as bad as the rule needs to distinguish. A finding is only shown above a severity of 0.35, so in practice a rule begins to speak about a third of the way up its own ramp.

Severities are absolute rather than ranked. That is deliberate and it is the whole reason the engine can conclude that nothing is wrong: a design that ranked the faults and always showed the worst one would manufacture a fault on a perfect drawing.

The provenance column is the part worth reading. Every number below was set from a measured fixture rather than chosen because it looked reasonable, and the sentence says which fixture.

Freehand circle

Flat Depthfires from 0.02 · saturates at 0.075
clean fixtures peak at 0.003 (0.003 on a phone at cssScale 2.2); a 5% wrist flattening measures 0.025 and an 11% one 0.060. 0.02 clears every clean case.
Ovalityfires from 0.045 · saturates at 0.09
clean 0.000-0.002. A 12% squash measures 0.064 and a 25% squash 0.140 — the second harmonic amplitude is (a-b)/(a+b), so 0.045 is roughly a 9% axis difference. full was 0.16, which is a circle so oval nobody needed telling; because a rule only fires at 35% of its ramp, that left a 14% oval scoring 69 with nothing named. Moved to 0.10, and landed 0.001 SHORT: a 12% oval measures 0.063 against a firing point of 0.064, so it scored 74 - under the clean floor - and the rule that knows it is an oval stayed silent by a hair. 0.09 puts the firing point at 0.061. An 8% oval measures 0.042, stays under t, and keeps its score of 84.
Wobblefires from 0.012 · saturates at 0.045
clean 0.001-0.003 on every device. 4px tremor measures 0.018, 9px measures 0.038. Ratcheting also lands here (0.010-0.017), which is why the motor group suppresses this one.
Closure Gapfires from 0.085 · saturates at 0.17
clean 0.002-0.005, phone 0.015. A 30px gap on a 150px circle measures 0.200. Threshold set above the phone case so coarse input never reads as an open circle.
Closure Overshootfires from 0.08 · saturates at 0.6
clean |0.00-0.01| rad; a deliberate 45deg overshoot measures 0.78 rad. t was 0.35 (20deg) and full was 1.2, which put the first point this rule could actually speak at 0.6475 rad = 37deg — and circle.not-closed stopped claiming the case at exactly 0.35, so 20-37deg of crossing was named by nobody: 40 of 40 readable attempts across five seeds came back clean at scores of 70-73 with the closure sub-score at 8-17, under a clean floor of 76. Now that not-closed is gated on the SIGN rather than on this magnitude, the positive side belongs entirely to this rule and its ramp starts where a crossing first becomes visible; 0.08/0.6 puts the firing point near 14deg and leaves no band. Swept over overshoots of 5/10/15/20/25/30/35/45/70deg at seeds 1,2,3,7,11.
Centre Driftfires from 0.055 · saturates at 0.14
single-pivot multi-lap fixtures 0.000; 20px drift per lap over 3 laps measures 0.281. Was 0.08/0.35, which started in the right place and then ramped so slowly that the rule could not reach the clean gate until 0.175 - and the SCORE was already at 47 by then. Swept over 4/6/9/12/15/18/24px of drift per lap: 6px measures 0.085 and scored 70 in silence, 9px measures 0.127 and scored 57 in silence, 12px measures 0.169 and scored 47 in silence. The band now reaches the gate at 0.085, which is the first point where the score crosses the engine own clean floor of 76, and 4px stays quiet at 0.057 and 81.
Radius Trendfires from 0.08 · saturates at 0.35
spiralling in or out between laps; same fixture family as centreDrift.
Micro Correctionsfires from 4 · saturates at 16
clean 0-1 across mouse 120Hz, stylus 240Hz and phone 60Hz. A 6-dip ratchet measures 6, a 12-dip ratchet 18, and 4-9px tremor 11-14.
Traced Norm Speedfires from 2.5 · saturates at 1
normSpeed is shape-lengths per second, so for a circle it is about 2*PI/duration. Committed fixtures sit at 7.3-24; a deliberately traced circle (5.2s) measures 1.22. NOTE: this threshold is inverted — lower is worse.
Cramped Radius Pxfires from 55 · saturates at 30
below roughly 55px on a 768x576 canvas the motion is finger-only regardless of device. NOTE: inverted — smaller is worse.
Hesitation Msfires from 2500 · saturates at 8000
a committed start is under ~800ms; 2.5s of hovering is a decision, not a delay.
Jerk Ratiofires from 2.6 · saturates at 5
clean 1.1-3.0 (rises with lap count); traced 3.7. Weak discriminator alone — used only as support.

Straight line

Kinkinessfires from 1.4 · saturates at 1.9
kinks of 10deg at t=0.5, 10deg at t=0.66 and 16deg at t=0.35 measure 1.6, 2.1 and 3.4. Bows with the same peak deviation (13, 22 and 43px) measure 1.0, 0.7 and 0.4. A 6deg kink measures 1.0 and is left to line.bow, because at that angle the claim would not be supportable. Swept across 210 ordinary lines — clean, bowed, trembling, hooked, on a phone and with 4px of jitter — the worst reading is 1.20, so the threshold clears every one of them with room to spare.
Retracefires from 0.06 · saturates at 0.35
every synthesised line — clean, bowed, trembling, ratcheting, on a phone — measures 0.000, because a stroke that only goes forwards cannot fall back. A stroke drawn to the far dot and 40% of the way back measures 0.398.
Bowfires from 0.018 · saturates at 0.075
clean fixtures under 0.004; a 20px bow on a 488px line measures 0.041 and 40px measures 0.082. 0.02 is roughly a 10px deviation — the point where it stops looking like a straight line.
Endpoint Errorfires from 0.023 · saturates at 0.12
clean 0.005-0.02 (a clean stroke still starts a few px off the dot); a 25px miss measures 0.05, 60px measures 0.12. t was 0.04, and severity has to clear the 0.35 clean gate before a rule speaks, so the first aiming finding arrived at 0.068 = 33px — leaving a band where a 30px miss scored 74 with nothing named, at five seeds out of five, under the engine's own clean floor of 76. 0.023 puts the firing point at 28px, which is where the score crosses 76. It is above the top of the clean range, so a clean stroke sits at severity 0 and a slightly-off one at 0.02 is still well under the gate. Swept over tilt and drift of 0-40px at seeds 1,4,5,9,13: no silent band, no clean line named.
Overshootfires from 0.035 · saturates at 0.15
clean ~0; running 40px past the far dot measures 0.082.
Wobblefires from 0.005 · saturates at 0.022
clean 0.001-0.003 across devices; 4px tremor measures 0.008 and 10px measures 0.020. This is the residual AFTER the intended bow is removed, so a smooth curve does not read as shake.
Ratchetfires from 3 · saturates at 12
clean 0-1 reversals; a deliberately ratcheted line produces 6-15.
Haltfires from 250 · saturates at 1200
a clean line measures 0. A single deliberate rest of 250ms scores 96 and stays quiet, 400ms scores 93 and stays quiet, 800ms scores 90 and is named. Before the commitment term was given a time form, all three scored 99 and none was named — the only thing that ever spoke was line.traced, at a stop of 1.5s, which is the wrong sentence for a line drawn quickly and stopped once.
Stopsfires from 1 · saturates at 6
every clean fixture measures 0 at 0-4px of jitter and 60/120/240Hz. A line drawn in four pushes with real halts measures 3, in six pushes 5, in eight pushes 7.
Traced Norm Speedfires from 0.6 · saturates at 0.2
a line is one shape-length, so normSpeed is about 1/duration. Committed fixtures sit at 1.5-4; a 3-second line measures 0.33. NOTE: inverted — lower is worse.

Ellipse in a plane

Lap Degree Spanfires from 1.5 · saturates at 6.5
clean 0.0-0.2 degrees. A second lap 6% rounder than the first spans 2.0, 10% spans 3.3, 20% spans 6.9 and 35% spans 12.4 — measured on paths that are analytically smooth, so the span is lap disagreement and nothing else.
Lap Tempofires from 0.72 · saturates at 0.35
clean 0.99-1.00, and a UNIFORMLY slow attempt also measures 1.00 — so this cannot double-count with ellipse.traced, which owns overall slowness. Second laps drawn at 0.8, 0.6 and 0.45 of the first read 0.80, 0.60 and 0.45, and every one of those scored 99 with nothing named. NOTE: inverted — lower is worse.
Degreefires from 5 · saturates at 14
degrees of asin(minor/major). Clean fixtures land within 2 of the target; a deliberately round ellipse (degree 45 in a 30-degree plane) measures 15. Was 6/26, which needed a 13-degree error before it would fire — an ellipse visibly too narrow for its box scored 70 and was told nothing was wrong.
Axisfires from 5 · saturates at 24
clean under 2 degrees; a 20-degree deliberate tilt measures close to 20.
Lopsidedfires from 0.012 · saturates at 0.055
sum of harmonics 3-5 of the radial error in the ellipse own unit-circle space. Orders 0-2 are absorbed by the fit itself (radius, centre, ovality) so they carry no information. Clean fixtures under 0.004; lopsided 0.18 measures ~0.018 and 0.30 measures ~0.032.
Wobblefires from 0.012 · saturates at 0.05
residual after harmonics 1-5 are removed, so a shape that is merely not-quite-an-ellipse does not read as shake. Clean under 0.003; an 8px tremor fixture measures ~0.030.
Fillfires from 0.12 · saturates at 0.45
fraction by which the fitted axes miss the plane. Clean under 0.04.
Off Targetfires from 0.14 · saturates at 0.75
a correctly shaped ellipse translated 80/160/240px off a box of mean radius 142 measures 0.56/1.13/1.88 and used to score 99 with two strengths attached. t at 0.14 is about 20px of drift on this box, which is inside the width of a confident stroke and should not be called a mistake; full at 0.75 is most of a radius, by which point the ellipse is alongside the box rather than on it.
Closurefires from 0.1 · saturates at 0.28
same family as the circle closure gap. Was only checked on a single-lap attempt, which meant a two-lap ellipse that stopped with its ends apart was named by nobody; the lap requirement now lives in ellipse.short-laps and this measures the gap wherever it happens. The floor is untouched and stays twice the noisiest clean reading — 24 exact two-lap ellipses peak at 0.0062, and 0.0498 at 3px of jitter. `full` came down from 0.34 because it left a hole above the floor: a 30px gap measures 0.181 and reached severity 0.34, missing the clean gate by 0.01 while the attempt scored 75 with nothing said about it.
Closure Overshootfires from 0.08 · saturates at 0.6
clean 0.00 rad. Sweeps of 2.05/2.15/2.30/2.60 laps against a two-lap target measure 0.31/0.94/1.88/3.77 rad, all of which scored 53-60 and were named by nobody before this existed. Shares the circle anchors: 0.08 fires near 14deg, which is where a crossing first becomes visible on a drawn-through shape.
Laps Shortfires from 2.2 · saturates at 5.5
a stroke 36deg short of two laps measures 0.63 and is a closure gap, not a missing lap; one that stopped after a single lap measures 6.28 and is a missing lap outright. t at 2.2 (126deg) and full at 5.5 (315deg) puts the boundary between them where the shape stops looking like a closed ellipse. Swept at sweeps of 1.0/1.5/1.9/2.0/2.05/2.15/2.3/2.6 laps.
Centre Driftfires from 0.08 · saturates at 0.35
shares the circle drill anchors — it is the same measurement in unit-circle space.
Micro Correctionsfires from 4 · saturates at 16
shares the circle drill anchors; the motor signature does not change with the shape.
Traced Norm Speedfires from 2.2 · saturates at 0.9
shape-lengths per second. An ellipse perimeter is shorter than its bounding circle, so the band sits slightly below the circle. NOTE: inverted - lower is worse.

Divide by eye

Hv Gapfires from 0.03 · saturates at 0.1
difference between the mean vertical error and the mean horizontal one. Clean fixtures under 0.006; a fixture with a 6% upward bias on verticals alone measures 0.060. Two bars per direction, so the threshold is set high enough that one stray mark cannot manufacture it — and proportion.one-off suppresses this finding outright.
Biasfires from 0.01 · saturates at 0.045
absolute mean signed error. Clean fixtures under 0.0005 (0.0003 on a phone at cssScale 2.2); a deliberate 3% late bias measures 0.030 and 5% measures 0.050. Set so that any attempt scoring below about 88 has something named — a score of 68 beside "nothing to correct" is the engine contradicting itself on one screen.
Spreadfires from 0.01 · saturates at 0.045
standard deviation of the signed errors, on the same ramp as bias because rms^2 = bias^2 + spread^2 exactly. That identity is what makes the pair EXHAUSTIVE: whenever the overall error is large, one of the two must be, so no real error can fall through both and leave the attempt reported as clean.
Separationfires from 4 · saturates at 10
chosen from the sweep above rather than from clean fixtures. Three bars per group is the minimum that supports the claim at all: with two per group the same sweep put 17 of 60 scattered attempts above every workable threshold, which is why the drill has six bars and not four.
Deliberation Effectfires from 0.02 · saturates at 0.07
measured on a fixture that checks three bars and hurries three: the hurried half lands 3, 4, 6 and 9% out against a checked half at 0.0%. 4% is the point where a visitor can see the difference between their own marks, and it now speaks.
Length Effectfires from 0.025 · saturates at 0.09
mean absolute error on the long bars minus the short ones. Clean fixtures within 0.004. Only the positive direction fires: worse-on-short is real but two bars cannot tell it apart from noise.
Outlierfires from 0.045 · saturates at 0.13
worst mark minus the mean of the other three. Clean under 0.006; three good marks plus one 12% miss measures 0.105. This is inattention, not a way of seeing, so it suppresses every aggregate finding it would otherwise fake.
Lapsefires from 0.025 · saturates at 0.07
worst mark, gated on the other five sitting within 2.5%. Five exact marks plus one out measures 3.3/4.8/5.8/7.3/11.8% at fixture values of 3.5/5/6/7.5/12%, and the same with a real hand under them (others within 1.5%) is unchanged. Six careless marks never reach it: the gate sees 4.0-6.9% among the rest and reads zero.
Rushed Msfires from 3600 · saturates at 1200
total time for SIX judgements — 600ms each at the threshold, 200ms at saturation. Actually comparing the two halves of a bar takes about a second; under a fifth of one is a reflex, not a judgement. NOTE: inverted — faster is worse, and it only fires alongside a real error, because fast and accurate is not a fault.

Draw the other half

Gain Errorfires from 0.05 · saturates at 0.15
injected gains are recovered exactly: 0.900, 0.800, 0.740 and 1.250 come back as 0.899, 0.800, 0.740 and 1.249 with a residual of 0.000. Clean fixtures measure 0.001-0.005; the worst ordinary reading the residual gate lets through is 0.039, and that case is the DRIFT fixture — itself a fault of another kind — rather than a clean drawing. The band starts speaking near 0.085, which is a 9% scale error: visible, worth 42 points of score, and exact wherever the residual is near zero.
Offset Normfires from 0.035 · saturates at 0.1
a flat −7px on every width measures 0.063 and a flat −14px measures 0.126, both with the gain at 0.999. Clean and wobbly fixtures measure 0.000-0.003.
Gain Residualfires from 0.03 · saturates at 0.12
exact 0.000, injected gains 0.000-0.001, a 16px wobble 0.088. Used only to refuse the shape findings, so a bulge or a tremor can never be read as a scale change.
Biasfires from 0.025 · saturates at 0.075
signed mean deviation over the widest half-width. A half traced exactly measures 0.00; halves drawn deliberately 4, 8 and 12 percent narrow measure -0.040, -0.079 and -0.118. t at 0.025 is about 2px on this vase, inside the width of a confident stroke; full at 0.075 is a half nobody would call symmetrical. Full was 0.11, then 0.085, and each left a band where the backstop spoke instead: at 0.11 an 8 percent wide half went unnamed, and at 0.085 a 7 percent narrow one did. 0.075 puts the firing point at 0.043, which is where the score crosses the clean floor.
Height Shiftfires from 0.03 · saturates at 0.105
the vertical slide, as a fraction of the vase height, that best fits the drawn profile onto the given one. Gated on heightExplains below, so it only speaks when sliding genuinely removes the error rather than merely reducing it. Full was 0.12, which left a 6 percent displacement one notch under the gate and handed it to the backstop, even though the slide explained ALL of its error.
Height Explainsfires from 0.45 · saturates at 0.9
the share of the average error that a pure vertical slide removes. A drawing that is simply wrong everywhere also has a best shift and it explains almost nothing; one whose widths are right and misplaced has most of its error removed by sliding.
Driftfires from 0.035 · saturates at 0.16
slope of absolute deviation against height, top to bottom. A steady half measures under 0.01; one that starts on the given half and is 10 percent out by the foot measures about 0.10.
Endpointsfires from 0.035 · saturates at 0.14
worst of the two ends, over the vase height. 0.035 is about 14px on this canvas, which is roughly a pen width and not worth mentioning below that.

Box in perspective

Family Imbalancefires from 0.25 · saturates at 0.9
boxes built by construction measure 0 at every jitter the fixtures produce, including 8 degrees of aim error and an opaque box with only nine edges. One edge rotated 18 degrees or more off its direction migrates to another family and measures 2, which is 0.5 here.
One Cornerfires from 0.025 · saturates at 0.18
a box built by construction measures 0.000, and so does one drawn 12px short at every corner — those ends still have neighbours. Pulling the three edges of the back corner apart measures 0.083 at 30px, 0.150 at 55px and 0.220 at 110px, while the MEDIAN corner gap stays under half a pixel throughout.
Corner Gapfires from 0.022 · saturates at 0.1
a box built by construction measures 0.000 - every corner has three ends on the same point. Edges pulled back 15, 30 and 45px from their corners on a 470px diagonal measure 0.045, 0.090 and 0.135, and all three scored 99 with a compliment before this existed. t at 0.022 is about 10px on that box, which is inside the width of a confident stroke.
Convergencefires from 0.9 · saturates at 3.4
RMS disagreement, in degrees, between the edges of one family and the single vanishing point that best fits them. Swept on boxes synthesised FROM exact vanishing points, so the correct answer is known before it is measured: a perfect box with ordinary capture noise measures 0.05-0.15 deg, a box drawn with 4 deg of aim error per edge measures around 2.4, and one at 9 deg falls apart entirely. Set from a sweep across eight seeds per jitter level rather than one, because a single seed put the firing point in the middle of the run-to-run spread: boxes at 3-4 deg were scoring in the mid-70s with nothing named, which is the score-versus-diagnosis contradiction the cross-drill suite exists to catch.
Parallelfires from 1.2 · saturates at 6
RMS spread, in degrees, of a family the chosen perspective mode says should stay parallel — the uprights in one- and two-point, and the level set in one-point too. Measured against the family mean rather than a fitted point, because least squares fits a vanishing point to four edges that lean together and reports near-zero disagreement, which would score the one fault that defines two-point perspective as perfect. t sits above hand tremor on a set of four edges; full is where the uprights are visibly splaying.
Separationfires from 0 · saturates at 0.4
already zeroed in the measurer at 28 deg between two families. Real three-quarter boxes run 30-45 deg; below about 24 the two horizontal sets read as one and the form flattens, so t is 0 — any remaining value is real.
Crowdingfires from 0.05 · saturates at 0.6
how far inside 1.5 box-diagonals the nearest vanishing point has come, which is roughly 40 deg of convergence across the form. Correct three-point boxes built from distant points measure 1.8-3.5 diagonals, so the zero point sits below anything a well-made box produces.
Wobblefires from 0.007 · saturates at 0.026
mean deviation of each edge from its own straight line, over its length. Swept on synthesised boxes: a clean edge measures 0.001, a just-visible bow 0.006, an obviously bowed edge 0.015 and a badly bent one 0.036 — so t sits above hand tremor and full at the worst realistic case. Shares its scale with the straight-line drill, so a wobble reported here means what it means there.
Throughfires from 0.5 · saturates at 6
how many of the twelve edges are missing. Drawing through the box is the instruction the exercise rests on, so t of 0.5 means any missing edge registers — but full is 6, so an opaque nine-edge box is a gentle note rather than the headline.

A cylinder in perspective

End Back Flatfires from 0.03 · saturates at 0.075
the inner half shallowed by 10/20/30/45/60% measures 0.008, 0.017, 0.027, 0.043 and 0.063 — and scored 99, 99, 99, 98 and 97 with nothing named at any of them. Noise on a correct cylinder: 0.0085 at 0.5px of jitter, 0.0128 at 1px, 0.0190 at 1.5px. The threshold sits 2.3x above the 1px reading.
End Pointedfires from 0.012 · saturates at 0.06
superellipse ends with extents identical to a true ellipse: exponent 2.0 measures -0.0000, 1.7 measures 0.029, 1.5 measures 0.051 and 1.3 measures 0.079, scoring 99, 97, 94 and 89 with nothing named. Noise 0.0023 at 0.5px, 0.0039 at 1px, 0.0066 at 1.5px — a signal-to-noise of 7:1 at the mildest case.
Funnelfires from 1.34 · saturates at 2.86
every correct fixture implies 1.41 to 3.00 canvas widths of viewing distance — the default cylinder 2.16, a long one 3.00, the shortest gradeable 1.41, and a strong but legitimate recession 1.97, which read 0.71 down to 0.33 here and are all clear of the threshold. A far end 59 degrees more open than the near one implies 0.29 canvas widths and reads 3.45.
Minor Axisfires from 4 · saturates at 22
degrees the worst end is rotated off square to the axis. A cylinder built by construction measures 0.0; fixtures cocked 12 and 25 degrees measure exactly 12.0 and 25.0, so the measurement has no noise in it at all and the band is entirely about what is worth saying. 4 is roughly where the tilt becomes visible on a 200px form; by 22 the cylinder reads as bent.
Degree Shiftfires from 0.12 · saturates at 0.75
shortfall in the near-to-far degree shift, as a fraction of a 12-degree ideal. A correct fixture shifts +8.7 degrees and scores 0 here; ends drawn at the same degree shift -0.0 and score 0.17, which clears t and is named.
Degree Backwardsfires from 1.5 · saturates at 9
degrees the far end is narrower than the near one - the wrong way round. A fixture built backwards measures 5.5. Starts at 1.5 because below that it is fitting noise rather than intent, and saturates at 9 where the form has clearly been drawn as a cone.
Tangent Missfires from 0.06 · saturates at 0.3
worst gap between a side and the end it should graze, over the widest end radius. Measured against the ellipse SUPPORT radius rather than a mean radius - the first version compared against the mean and reported 0.307 on a cylinder exact by construction, which now measures 0.002. Ends cocked 12 and 25 degrees measure 0.041 and 0.126, which is honest: a rotated end really does pull away from its own silhouette.
Taperfires from 0.1 · saturates at 0.8
shortfall in narrowing toward the far end. A correct fixture tapers 0.242 and scores 0; parallel sides taper 0.000 and score 0.2. Negative taper - wider at the far end - runs further up the same ramp.
Side Bowfires from 0.02 · saturates at 0.09
worst side bow over its own length. Shares the line drill anchors, where a straight stroke measures under 0.005 on every device.

The rules we hold ourselves to

What the engine refuses to do

  • It will not score what it cannot read

    A stroke that fails a validity gate returns “we could not read that” and no number at all — never a zero and never a guess. Without those gates a three-point tick mark fits a tiny circle perfectly and scores in the nineties.

  • It will not claim a cause it cannot know

    A shoulder pivot has a radius of about 60cm, so a 5cm circle on a phone is not a shoulder movement no matter who drew it. Findings about WHERE your line went wrong are stated on every device; findings about WHICH JOINT caused it appear only for a stylus, and the page says so.

  • It will not invent timing it does not have

    Some devices report every point of a stroke with one clock reading. When that happens the confidence figure is withheld and every timing-derived finding is suppressed, rather than announcing that your circle took 0.0 seconds and accusing you of tracing.

  • It will not tell you that you improved when you did not

    The honest response to some findings is “draw faster”, which reliably lowers accuracy on the next attempt. Rather than hide that, each finding carries its expected effect, and when the correct fix costs accuracy the result headlines confidence instead and says the score may dip.

  • It will not rank you against other people yet

    The level bands are absolute thresholds, and the page that shows them says so. “Better than 62% of beginners” would be a fabricated number in a product whose whole claim is that its numbers are measured. It becomes available when enough people have taken the test for the comparison to be real.

  • It will not score a dimension it did not measure

    Shading is not recoverable from the geometry of a stroke, so the skill profile leaves that axis open and labelled rather than plotting it at zero — which would tell every visitor they are bad at something nobody looked at.

Limits

What these measurements cannot see

Whether the drawing is any good. Every quantity here is a relationship between shapes. A perfectly round circle can sit in a drawing that does not work, and a drawing can work with shaky circles all through it. For a reading of an actual drawing — proportion against your reference, shading, what to fix first — that is what Rate My Sketch is for.

Rendering. Lashes, lid folds, edges, texture, how light falls. None of it is in a stroke's geometry.

Your hand, separately from your device. Most of the drills measure motor control, which is partly a measurement of what you drew with. The proportion drill is the exception — placing a tick costs almost nothing to execute on any input, so what is left is judgement, and judgement carries over to paper unchanged.

Whether these thresholds match real beginners. They were set from synthetic fixtures, which pin the geometry exactly but say nothing about how often a real person lands on either side of a line. They will be re-anchored against real attempts, and this page will change when they are.

Try it against your own hand

Every drill is free and unlimited

Nothing is uploaded, nothing is stored unless you ask, and the arithmetic above runs on your device.

Open the drills