[Question]
  [
From <http://en.wikipedia.org/wiki/Triangle>:
![enter image description here](https://i.stack.imgur.com/24dz3.png)
---
Write a program that takes three 2d coordinate tuples (Cartesian), and classifies what shape these three points describe.
In almost all cases these points will describe a triangle of varying types. In some degenerate cases, the points will either describe a singular point or a straight line. The program will determine which of the following tags apply to the described shape:
* Point (3 points are co-incident)
* Line (3 points lie on a straight line - no more than 2 points may be co-incident)
* Equilateral (3 sides equal, 3 angles equal)
* Isosceles (2 sides equal, 2 angles equal)
* Scalene (0 sides equal, 0 angles equal)
* Right (1 angle exactly π/2 (or 90°))
* Oblique (0 angles exactly π/2 (or 90°))
* Obtuse (1 angle > π/2 (or 90°))
* Acute (3 angles < π/2 (or 90°))
Note that for some described shapes, more than one of the above tags will apply. For example, any right-angled will also either be isosceles or scalene.
### Input
* The program may read the 3 input coordinates from STDIN, command-line, environment variables or whatever method is convenient for your language of choice.
* The input co-ordinates my be formatted however is convenient for your language of choice. It can be assumed that all input numbers are well-formed with respect to the datatypes you end up using.
* Nothing can be assumed about the ordering of the input coordinates.
### Output
* The program will output to STDOUT, dialog box or whatever display method is convenient for your language of choice.
* The output will display all the tags applicable to the shape described by the input coordinates.
* Tags may be output in any order.
### Other Rules
* Your language's trigonometric libraries/APIs are allowed, but any APIs that specifically calculate triangle types are banned.
* When determining equality of angles or lengths of sides, you will likely end up comparing floating-point values. Two such values are to be considered "equal" if one is within 1% of the other.
* [Standard “loopholes” which are no longer funny](http://meta.codegolf.stackexchange.com/questions/1061/standard-loopholes-which-are-no-longer-funny)
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest answer in bytes wins.
### Examples
```
Input                   Output
(1,2) (1,2) (1,2)       Point
(1,2) (3,4) (5,6)       Line
(0,0) (1,1) (2,0)       Isosceles Right
(0,0) (2,1) (10,1)      Scalene Oblique Obtuse
```
  
[Answer]
# C (451 bytes)
Uses only squared lengths and slopes.
```
p[2],q[2],r[2];z(c){char*y[]={"Line","Point","Isosceles ","Equilateral ","Scalene ","Right","Oblique ","Acute","Obtuse"};printf(y[c]);}d(int*a,int*b){int c=*a++-*b++,e=*a-*b;return c*c+e*e;}main(){scanf("%d%d%d%d%d%d",p,p+1,q,q+1,r,r+1);int a=d(p,q),b=d(q,r),c=d(r,p),e=!a+!b+!c,f=(a==b)+(b==c)+(c==a),g=a>b&&b>c?a:b>c?b:c,h=g^a?g^b?a+b:c+a:b+c;e?z(e/2):(1[q]-1[p])*(*r-*q)^(1[r]-1[q])*(*q-*p)?f?z(2+f/2),f-1&&z(2):z(4),h^g?z(6),z(7+(h<g)):z(5):z(0);}
```
Ungolfed (and ternary operator replaced with if/else):
```
int p[2],q[2],r[2];
void print(c){
    char *y[]={"Line","Point","Isosceles ","Equilateral ","Scalene ","Right","Oblique ","Acute","Obtuse"};
    printf(y[c]);
}
squared_distance(int *a,int *b){
    int c = *a++ - *b++, e = *a - *b;
    return c*c+e*e;
}
main(){
    scanf("%d%d%d%d%d%d",p,p+1,q,q+1,r,r+1); // read in coordinates
    int a = squared_distance(p,q),b = squared_distance(q,r),c = squared_distance(r,p),
    e=!a+!b+!c, // number of sides of length 0
    f=(a==b)+(b==c)+(c==a), // number of equal-length pairs
    g = a > b && b > c ? a : (b > c ? b : c), // longest side
    h = g != a ? g != b ? a + b : c + a : b + c; // sum of squares of length of other two sides
    if(e)
        print(e/2); // 1 side of len 0: line, 3 sides: point
    // comparing slopes PQ and QR
    else if((q[1]-p[1])*(*r-*q) != (r[1]-q[1])*(*q-*p)){ // not line
        if(f){
            print(2+f/2); // 1 pair of equal length sides: isosceles, 3: equilateral
            if(f-1) print(2); // equilateral therefore also isosceles
        }else print(4); // 0: scalene
        if(h!=g){ // a^2+b^2!=c^2: not right
            print(6); // oblique
            print(7+(h<g)); // a^2+b^2<c^2:obtuse, acute otherwise 
        }else print(5); // right
    }else
        print(0); // line
}
```
Input (through stdin) Format: x y x y x y
ex. 0 0 1 1 2 0 for Isosceles Right
[Answer]
# C,333
```
z,c,r,b,s,i,t[14],g[14];
main(){ 
  for(;i<14;i++){
    g[i]=r=t[(i+2)%6]-t[i%6];r*=r;t[i|1]+=r;
    i<6&&scanf("%d",t+i);
    i>7&&(b<t[i]&&(b=t[i]),s+=t[i],z+=!t[i],c+=t[i]==t[i-2]);  
  }
  if(g[6]*g[9]==g[8]*g[7])puts(z==6?"point":"line");else
    printf(b*2==s?"right ":"oblique %s",b*2>s?"obtuse ":"acute "),puts(c>3?c>5?"equilateral":"isosceles":"scalene");
}
```
I left the whitespace in for the moment. This works but could probably do with some tidying up and golfing. Similar math to `@es1024`'s answer, but uses a loop and arrays. Input format `x y x y x y`
Variables
`t[]` stores both the input and the squares of the lengths. By the end of the program it looks like the table below (increasing the number of iterations of the loop would lead to indefinite repitition of the squared lengths.) At the start of the loop squares of lengths (garbage as not all the data is available) are needlessly stored in cells 1,3 and 5, but are promptly overwritten by `scanf.` Useful data is written to `z,b,c` ahd `s` when `i`=9,11,13 (`t[i]` and `t[i-2]` are accessed.)
```
01 23 45 67 89 1011 1213
aa bb cc  a  b    c    a
xy xy xy  L  L    L    L
```
`g[]` was added late on to hold the dx and dy values needed for slope calculation. The only cells used are 6 through 9 (0 through 5 are unreliable as not all the data is available when they are written.) If `g[6]/g[7]==g[8]/g[9]` the slopes of 2 lines are equal and the triangle is just a line (or a point.) The equation is rearranged in the program to avoid division.
`r`is an intermediate value used for squaring
`z`counts the number of sides of length zero. It has an offset of +3 because the loop reads 3 blank cells in `t[]`.
`c`counts the number of sides that are of identical length. It also has an offset of +3. Note that side `a` is written to `t[]` twice in order to be able to check a=b,b=c,c=a.
`b`is the biggest length of a side, squared.
`s`is the sum of the squares of all sides.
Note that comparing side lengths A^2+B^2+C^2 with 2\*B^2 is the same as comparing A^2+C^2 with B^2 (just subtract B^2 from both sides.) Thus if B^2=A^2+C^2 it is a right triangle. if B^2 is greater it is obtuse, if smaller it is acute.
[Answer]
# Golfscript (175 bytes)
```
~..|,({.)2$([\;\]@(;]{{~}/@- 2?@@- 2?+}%$.{2-1??100*}/-+abs 1<{;"Line"}{.[]|,((["Isosceles ""Scalene "]=\~-+.!["Oblique ""Right "]=\.!\0>-)["Acute ""Obtuse "]=}if}{;"Point "}if
```
You can test it [here](http://golfscript.apphb.com/?c=e117cHJpbnR9L24gcHJpbnR9OnE7Cjt7fi4ufCwoey4pMiQoW1w7XF1AKDtde3t%2BfS9ALSAyP0BALSAyPyt9JSQuezItMT8%2FMTAwKn0vLSthYnMgMTx7OyJMaW5lIn17Li58LCgoWyJJc29zY2VsZXMgIiJTY2FsZW5lICJdPVx%2BLSsuIVsiT2JsaXF1ZSAiIlJpZ2h0ICJdPVwuIVwwPi0pWyJBY3V0ZSAiIk9idHVzZSAiXT19aWZ9ezsiUG9pbnQgIn1pZn06ZjsKCiJbWzEgMV1bMyAyXVs3IDRdXSIgZiBxICMgTGluZQoiW1swIDddWzAgN11bOCAxXV0iIGYgcSAjIExpbmUKIltbMCA3XVswIDddWzAgN11dIiBmIHEgIyBQb2ludAoiW1sxIDRdWzkgN11bNCAwXV0iIGYgcSAjIFNjYWxlbmUgT2JsaXF1ZSBBY3V0ZQoiW1swIDBdWzQgMF1bMCAzXV0iIGYgcSAjIFNjYWxlbmUgUmlnaHQgCiJbWzEgNF1bOSAxXVs0IDBdXSIgZiBxICMgU2NhbGVuZSBPYmxpcXVlIE9idHVzZQoiW1swIDBdWzQgMF1bMiAzXV0iIGYgcSAjIElzb3NjZWxlcyBPYmxpcXVlIEFjdXRlCiJbWzAgMF1bNCAwXVsyIDJdXSIgZiBxICMgSXNvc2NlbGVzIFJpZ2h0CiJbWzAgMF1bNCAwXVsyIDFdXSIgZiBxICMgSXNvc2NlbGVzIE9ibGlxdWUgT2J0dXNlIAoK) (test set included).
**Input format:**
```
"[x y][x y][x y]"
```
**Commented version:**
```
~                       # evaluates input string          
..|,(                   # pushes the number of unique coords - 1
{
  .)2$([\;\]@(;]        # makes all 3 possible pairings of coords
  {{~}/@- 2?@@- 2?+}%$  # gets all squares of side lengths 
  .{2-1??100*}/-+abs 1< # 0 if triangle, 1 if line
  {;"Line"}
  {
     .[]|,((["Isosceles ""Scalene "]=\   # removes duplicate side-squares,
                                         #   and use the count to determine
                                         #   if isosceles or scalene (no
                                         #   equilaterals will exist)
     ~-+.!["Oblique ""Right "]=\         # compute a^2 + b^2 - c^2. Use to
                                         #   determine if oblique or right.
                                         #   c = max side length 
     .!\0>-)["Acute ""Obtuse "]=         # use same value to determine if
                                         #   acute, obtuse, or right
  }
  if
}
{;"Point "}
if
```
**NOTE:**
The reason my code contains no "equilateral" output is because:
* OP said "all input numbers are well-formed with respect to the datatypes you end up using"
* Golfscript does not have floating point numbers - not inherently anyway
* It's impossible (in a 2-dimensional grid) to have an equilateral triangle with integer coordinates, as proven [here](https://math.stackexchange.com/questions/105330/equilateral-triangle-with-integer-coordinates).
[Answer]
# Mathematica (~~313~~ 307 characters)
Golfed:
```
f@p_:=(P=Print;R=RotateLeft;L=Length;U=Union;If[L@U@p==1,P@"Point",If[Det[Join[#,{1}]&/@p]==0,P@"Line",v=p-R@p;a=MapThread[VectorAngle[#,#2]&,{-v,R@v}];u=L@U[Norm/@v];If[u==1,P@"Equilateral",If[u==2,P@"Isosceles",P@"Scalene"]];If[MemberQ[a,Pi/2],P@"Right",P@"Oblique";If[Max@a>Pi/2,P@"Obtuse",P@"Acute"]]]])
```
Ungolfed:
```
f@p_ := (
  P = Print;    (* make aliases for functions used more than once *)
  R = RotateLeft;
  L = Length;
  U = Union;
  If[L@U@p == 1,    (* if all points identical *)
   P@"Point",
   If[Det[Join[#, {1}] & /@ p] == 0,    (* if area is zero *)
    P@"Line",
    v = p - R@p;    (* cyclic vectors *)
    a = MapThread[VectorAngle[#, #2] &, {-v, R@v}];    (* interior angles *)
    u = L@U[Norm /@ v];    (* number of unique side lengths *)
    If[u == 1,
     P@"Equilateral",
     If[u == 2,
      P@"Isosceles",
      P@"Scalene"
      ]
     ];
    If[MemberQ[a, Pi/2],
     P@"Right",
     P@"Oblique";
     If[Max@a > Pi/2,
      P@"Obtuse",
      P@"Acute"
      ]
     ]
    ]
   ]
  )
```
The input format is a list of points, upon which the function is called:
```
points = {{x1,y1},{x2,y2},{x3,y3}};
f@points
```
]