Calculate the Orthocenter of a Triangle

9

0

Try to write the shortest program or function you can that prints or returns the calculated orthocenter of a triangle.

The orthocenter of a triangle is the intersection point of the three altitudes of a triangle. The altitude of a triangle is a perpendicular segment from the vertex of the triangle to the opposite side.

Input:

  • Three points in 2D space correponding to the triangle's vertices

Output:

  • The calculated orthocenter of the triangle

A sample input would be

A(0,0)
B(3,6)
C(6,0)

and a sample output would be:

Calculated Othocenter (3, 1.5)

One formula for orthocenter can be written as

(x, y) = ((ax*tan(α) + bx*tan(β) + cx*tan(γ))/(tan(α) + tan(β) + tan(γ),
          (ay*tan(α) + by*tan(β) + cy*tan(γ))/(tan(α) + tan(β) + tan(γ))

Shortest program in bytes wins.

Roberto Duran

Posted 2015-06-27T05:02:22.043

Reputation: 97

Question was closed 2016-01-11T13:55:53.333

I added a description, and yes, the use of global's as a function was a slip up on my part, I copy and pasted from the wrong notepad file I had open without realizing it. The use of arrays is purely optional, it is just a habit of mine to do so, vs a naming convention like Ax, Ay, Bx... – Roberto Duran – 2015-06-27T05:33:36.630

Welcome to PPCG. Language specific challenges are frowned on here, because they limit participation and are frequently homework questions in disguise. I will cast a reopen vote if the language restriction is removed (and I say this despite the fact that most of my answers are in C.) – Level River St – 2015-06-27T09:33:45.910

3I cleaned this whole thing up for you, but you need to specify how the points are to be supplied to the function or program and what exactly the points are (angles, coordinates?) – Beta Decay – 2015-06-27T10:00:33.350

@BetaDecay it was fairly clear to me that the given points and required orthocentre are x.y coordinates. See 3rd comment from the top. – Level River St – 2015-06-27T10:04:06.417

4This question would benefit greatly from a good set of test cases; and, as with all questions involving floating point numbers, the spec isn't complete without a carefully thought out constraint on numerical accuracy. – Peter Taylor – 2015-06-27T11:09:36.570

For a triangle or any shape? My attempt but it's really ugly and I don't know if I should really post it as an answer

– Downgoat – 2015-06-27T13:19:26.950

Since your input is defined as "several points", what's the definition of the orthocenter for more than 3 points? What if there are less than 3 points in the input? – Reto Koradi – 2015-06-27T16:05:26.083

3 points is a mandatory input, cases in which there is a missing point are out of the scope of this challenge, or course, one could write a program to find that missing side. – Roberto Duran – 2015-06-27T20:19:41.767

Is web scraping allowed? – rp.beltran – 2015-06-30T18:03:00.047

As in using an online resource to do it for you?(Example -curl and an online calculator?)No – Roberto Duran – 2015-06-30T20:36:37.510

Answers

3

Python, 193 168

Should work for any valid triangle...

def h(a,A,b,B,c,C):
 if A==B:b,B,c,C=c,C,b,B
 m=(a-b)/(B-A)
 return m,C-m*c
def f(a,A,b,B,c,C):
 m,q=h(a,A,b,B,c,C)
 k,z=h(c,C,b,B,a,A)
 x=(q-z)/(k-m)
 return (x,k*x+z)

Pawn

Posted 2015-06-27T05:02:22.043

Reputation: 51

3

CJam, 90 bytes

q~:C2$]_2ew::.-:D;;D1=0=D2=0=*D1=1=D2=1=*+D0=1=D2=0=*D0=0=D2=1=*-/_D0=1=*C0=+C1=@D0=0=*-S\

Try it online

CJam isn't really optimized for geometry, so the code isn't doing anything fancy. It uses the parametric representation for two of the lines passing through a corner and being orthogonal to the opposite side, and solves the 2x2 system of equations resulting from intersecting the two lines. Well, it only needs one of the resulting parameters, which is then used for calculating the intersection point.

Note that some of the signs in the intermediate values are wrong. Instead of flipping them with additional code, I kept them the way they are, and corrected for the wrong sign by changing additions to subtractions (or vice versa) when the value is used later. For example, if you see a + where you would normally expect a - when calculating a determinant, that's because one of the terms has the wrong sign. In fact, both determinants have the wrong sign (at least relative to my paper notes), but that doesn't matter because they are divided by each other.

Since the input format was not precisely specified, I made it CJam friendly. The code expects 3 points in CJam array format, where the values have to be floating point. For the given example, the expected input is:

[0. 0.] [3. 6.] [6. 0.]

Explanation:

q~      Get and interpret input.
:C      Store away the last point in variable C. Will be needed at the end
        to calculate the intersection point.
2$]     Repeat the first point, and wrap all points in an array.
_2ew    Generate array with all pairs of points [[A B] [B C] [C A]].
::.-    Calculate the vector difference of all point pairs [A-B B-C C-A].
        These are the vectors for each side of the triangle.
:D;;    Store the side vectors in a variable, and clear the stack.
D1=0=D2=0=*D1=1=D2=1=*+
        Calculate determinant for first unknown in 2x2 system of equations.
D0=1=D2=0=*D0=0=D2=1=*-
        Calculate main determinant of 2x2 system of equations.
/       Divide the two determinants. This gives the parameter of the
        intersection point for the line starting at C and orthogonal to A-B.
_       Copy it because we'll need it twice.
D0=1=*C0=+
        Calculate x-coordinate of intersection point.
C1=@D0=0=*-
        Calculate y-coordinate of intersection point.
S\      Put a space between the two values.

Reto Koradi

Posted 2015-06-27T05:02:22.043

Reputation: 4 870

2

R, 102 70 68 bytes

As an unnamed function which implements the formula in the question. The parameter for the function a vector of complex numbers (X+Yi) and it returns a complex number. I'm assuming that complex numbers are okay for input and output.

function(E)sum((F=tan((D=Arg(E-E[c(3,1,2)]))-D[c(2,3,1)]))*E)/sum(F)

Edit Vectorized it a lot

Expanded explanation

f=function(E){
    D=Arg(E-E[c(3,1,2)]); # Angles of sides
    F=tan(D-D[c(2,3,1)]); # Internal triangle angles tangents
    sum(E*F)/sum(F);      # Orthocenter coordinate return
}

Test

> f=function(E)sum((F=tan((D=Arg(E-E[c(3,1,2)]))-D[c(2,3,1)]))*E)/sum(F)
> f(c(0+0i,3+6i,6+0i))
[1] 3+1.5i

MickyT

Posted 2015-06-27T05:02:22.043

Reputation: 11 735

Is the code shorter if you use complex numbers or just required for the calculation? – Beta Decay – 2015-06-30T18:17:54.630

@BetaDecay both really. They made the calculation easier and shorter. If it turns out that they aren't allowed as input or output I would probably still us them internally. – MickyT – 2015-06-30T18:46:34.177

0

Cobra - 247

def f(p as System.Drawing.Point[])
    a,b,c=p
    d,e,f=for q in[[b,c],[a,c],[a,b]]get if(z=q[0].x-q[1].x,(q[0].y-q[1].y)/z,0f)
    print (a.x*(g=((e-f)/(1+e*f)).abs)+b.x*(h=((d-f)/(1+d*f)).abs)+c.x*(i=((e-d)/(1+e*d)).abs))/(j=g+h+i),(a.y*g+b.y*h+c.y*i)/j

Οurous

Posted 2015-06-27T05:02:22.043

Reputation: 7 916