You probably know that if you draw all three altitudes of a triangle, they will meet at a single point, the orthocenter.

I'm trying to draw a picture that shows the intersecting altitudes with TikZ and letting TikZ do most of the job for me. I'm using TikZ's coordinate calculation capabilities for that.

Here is the code:

\coordinate (A) at (0,0);
\coordinate (B) at (1,2.5);
\coordinate (C) at (4,0);
\draw (A) -- (B) -- (C) -- cycle;
\draw (B) -- ($(A)!(B)!(C)$) ++(90:0.2) -- ++(0:0.2) -- +(-90:0.2);
\draw (A) -- ($(B)!(A)!(C)$) ++(-39.806:0.2) -- ++(50.194:-0.2) -- +(-39.806:-0.2);
\draw (C) -- ($(A)!(C)!(B)$) ++(68.2:-0.2) -- ++(-21.8:0.2) -- +(68.2:0.2);

Here is the result:

enter image description here

Upon very close inspection (e.g., if you view the resulting pdf file with a pdf-reader and zoom in as close as possible) you can see that the three altitudes do not meet at a single point but instead meet in pairs, producing three distinct intersections.

Here's an image of the "intersection point" at 1600%

enter image description here

I also tried with different line widths, i.e. I used [very thin] on the whole {tikzpicture} environment but the problem persists.

I feel the reason for this inaccuracy might be due to numeric precision to which TikZ calculations are limited. However, I am still wondering if anyone has encountered this problem or knows of a solution? Or maybe that's the wrong method to draw altitudes?

P. S. while not a very big problem it still feels disappointing to know your pictures only look correct when not zoomed in on.

  • Did you try with scale=1 ?
    – percusse
    Jul 21, 2015 at 14:54
  • 1
    I added an image of the resulting intersection with your code. I hope it's OK. Jul 21, 2015 at 14:56
  • @percusse The problem persists with scale=1. Jul 21, 2015 at 14:57
  • @Gonzalo Medina: yes, that's a useful addition. @percusse: The problem was initially discovered with scale=1.
    – Rokas
    Jul 21, 2015 at 14:59
  • 2
    This seems like a duplicate of Calculating right angle triangle side inside LaTeX? See the excellent answer by Alain Mathes. Jul 21, 2015 at 15:06

3 Answers 3


This is, indeed, due to some inaccuracies in PGF, and can actually been seen in the manual in the section on coordinate calculations. More specifically it appears to be down to the the \pgfpointnormalised command which has been around for years (i.e., prior to the math engine) but has never been updated.

Armed with an alternative definition, the altitudes intersect with considerably more accuracy:

  \pgfmathcos@{\pgf@tmp}\pgf@x=\pgfmathresult pt\relax%
  \pgfmathsin@{\pgf@tmp}\pgf@y=\pgfmathresult pt\relax%
  spy using outlines={circle, magnification=10, size=2cm, connect spies}]
\path (0,0) coordinate (A) (1,2.5) coordinate (B) (4,0) coordinate (C);
\draw (A) -- (B) -- (C) -- cycle;
\draw [red, opacity=0.5, very thin] 
  (A) -- ($(B)!(A)!(C)$) (B) -- ($(A)!(B)!(C)$) (C) -- ($(A)!(C)!(B)$);
\spy [red] on (1,1.2) in node at (3.5,1.5);

  spy using outlines={circle, magnification=10, size=2cm, connect spies}]
\path  (0,0) coordinate (A) (1,2.5) coordinate (B) (4,0) coordinate (C);
\draw (A) -- (B) -- (C) -- cycle;
\draw [blue, opacity=0.5, very thin] 
  (A) -- ($(B)!(A)!(C)$) (B) -- ($(A)!(B)!(C)$) (C) -- ($(A)!(C)!(B)$);
\spy [blue] on (1,1.2) in node at (3.5,1.5);

enter image description here

  • Thanks! This is exactly the answer I was anticipating. I inserted your code into my documents to fix the diagrams and it works perfectly. Sadly, though, I have not the slightest idea about what exactly the fix does and why it works. Also, it would be nice if this fix were included in TikZ source code but it seems to me no one is actively working on TikZ anymore.
    – Rokas
    Jul 24, 2015 at 15:53
  • 1
    @Rokas \pgfpointnormalised simply converts a 2D-coordinate to a unit-vector (i.e. same angle but with length 1pt). It is used in the calculation of orthogonal projections (and in a bunch of other places). The original version was very fast, but a bit inaccurate (maybe only to around 1 degree) and the inaccuracies were magnified with subsequent calculations, the version I put in above is orders of magnitude slower but comparatively more accurate. You could put in a feature request or a bug report here so it doesn't get forgotten. Jul 25, 2015 at 17:52
  • 3
    @Mark Wibrow: submitted a feature request, ticket #96.
    – Rokas
    Jul 26, 2015 at 9:48
  • 1
    3 year later, I notice that this error has not been fixed so far (29 Sep 2018)! why is that?
    – Black Mild
    Sep 29, 2018 at 13:37
  • 4
    This has been fixed upstream: sourceforge.net/p/pgf/git/ci/… Feb 28, 2019 at 8:00

For comparison, here's one way to construct and draw altitudes in Metapost; the orthocenter looks correct even when zoomed in.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";


u = 2cm;

z1 = origin;
z2 = (1u,2.5u);
z3 = (4u,0);

z4 = whatever[z2,z3]; z4-z1 = whatever * (z3-z2) rotated 90;
z5 = whatever[z3,z1]; z5-z2 = whatever * (z1-z3) rotated 90;
z6 = whatever[z1,z2]; z6-z3 = whatever * (z2-z1) rotated 90;

drawoptions(withcolor .7 white);
draw unitsquare scaled 1/8u rotated angle (z2-z3) shifted z4;
draw unitsquare scaled 1/8u rotated angle (z3-z1) shifted z5;
draw unitsquare scaled 1/8u rotated angle (z1-z2) shifted z6;

drawoptions(withcolor .7 blue);
draw z1--z4;
draw z2--z5;
draw z3--z6;

draw z1--z2--z3--cycle;


Another comparison, with pstricks, and its module pst-eucl: Euler's nine-point circle (adapted from pst-eucl documentation):

    \documentclass[12pt, pdf, x11names]{article}%



\psset{unit=2,dotsize = 2pt}
    {% local modification of parameters
        \psset{linestyle=none, PointSymbolB=none, PointNameB=none}
    }% fin
    {% local modification of parameters
        \psset{nodesep=-.8, linecolor=DarkSeaGreen3}
    }% end
    { \psset{CodeFig, CodeFigColor=LightSteelBlue2, CodeFigStyle=solid, linewidth=0.6pt, RightAngleSize=0.125}
    % Euler circle (centre is the midpoint of [OH])
    \pstMiddleAB[PointSymbol=*, PointName=\omega, PosAngle=0]{O}{H}{omega}
    \pstCircleOA[linecolor=Coral2, linestyle=dashed, dash=3.5mm 1.5mm]{omega}{B'}
    % Passe through the midpoints of the segments joining the orthocentre to vertices


enter image description here

6400 × zoom:

enter image description here

  • @sergej: Done. I translated the comments into English. Thanks.
    – Bernard
    Jul 25, 2015 at 9:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .