Go: package main

import (
        "fmt"
)

func main() {
        var x1, y1, x2, y2, x3, y3, px, py float64
        var oax, oay, obx, oby, opx, opy float64
        var det float64
        var s, t float64

        for {
                _, err := fmt.Scanf("%f %f %f %f %f %f %f %f", &x1, &y1, &x2, &y2, &x3, &y3, &px, &py)
                if err != nil {
                        break
                }
                oax = x2 - x1
                oay = y2 - y1
                obx = x3 - x1
                oby = y3 - y1
                opx = px - x1
                opy = py - y1
                det = oax*oby - obx*oay

                if det == 0 {
                        fmt.Printf("NO\n")
                } else {
                        s = (oby*opx - obx*opy) / det
                        t = (oax*opy - oay*opx) / det

                        if (s+t < 1 && s > 0 && t > 0) {
                                fmt.Printf("YES\n")
                        } else {
                                fmt.Printf("NO\n")
                        }
                }
        }
}

C++: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define dump(a) (cerr << (#a) << " = " << (a) << endl)
#define FOR(it,c) for(__typeof((c).begin())it=(c).begin(); it!=(c).end();++it)
#define RFOR(it,c) for(__typeof((c).rbegin())it=(c).rbegin(); it!=(c).rend();++it)
#define exist(c, v) (find((c).begin(), (c).end(), (v)) != (c).end())

template<class T> inline void chmax(T& a, const T& b) { if(b > a) a = b; }
template<class T> inline void chmin(T& a, const T& b) { if(b < a) a = b; }

template<typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os << '(' << p.first << ", " << p.second << ')';
	return os;
}

template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
	copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
	return os;
}

const double EPS = 1e-9;

struct point {
	double x, y;
	point():x(0), y(0) {}
	point(double x, double y):x(x), y(y) {}
	point(const point& p):x(p.x), y(p.y) {}

	point operator+ (const point& p) const {
		return point(x + p.x, y + p.y);
	}

	point operator- (const point& p) const {
		return point(x - p.x, y - p.y);
	}

	point operator* (const double s) const {
		return point(x * s, y * s);
	}

	point operator* (const point& p) const {
		return point(x * p.x - y * p.y, x * p.y + y * p.x);
	}

	point operator/ (const double s) const {
		return point(x / s, y / s);
	}

	bool operator< (const point& p) const {
		return x + EPS < p.x || abs(x - p.x) < EPS && y + EPS < p.y;
	}

	bool operator== (const point& p) const {
		return abs(x - p.x) < EPS && abs(y - p.y) < EPS;
	}
};

inline double abs(const point& p) {
	return sqrt(p.x * p.x + p.y * p.y);
}

inline double norm(const point& p) {
	return p.x * p.x + p.y * p.y;
}

inline double dot(const point& l, const point& r) {
	return l.x * r.x + l.y * r.y;
}

inline double cross(const point& l, const point& r) {
	return l.x * r.y - l.y * r.x;
}

struct segment {
	point a, b;
	segment(point a, point b):a(a), b(b){}
};

typedef vector<point> polygon;

inline int ccw(const point& a, point b, point c) {
	b = b - a;
	c = c - a;
	const double tmp = cross(b, c);
	if(tmp > EPS) return 1; // ccw
	if(tmp < -EPS) return -1; // cw
	if(dot(b, c) < 0) return 2; // c, a, b 順に一直線上
	if(norm(b) < norm(c)) return -2; // a, b, c 順に一直線上
	return 0; //a, c, b 順で一直線上
}

inline bool intersect(const segment& s, const segment& t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
		ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

inline bool intersect(const segment& s, const point& p) {
	return ccw(s.a, s.b, p) == 0;
}

inline point crosspoint(const segment& s, const segment& t) {
	if(!intersect(s, t)) // 交点を持たない
		return s.a; // 用改善

	const double tmp = cross(s.b - s.a, t.b - t.a);
	if(abs(tmp) < EPS) { // 一直線上
		if(intersect(s, t.a)) return t.a;
		if(intersect(s, t.b)) return t.b;
		if(intersect(t, s.a)) return s.a;
		return s.b;
	}

	return t.a + (t.b - t.a) * cross(s.b - s.a, s.b - t.a) * (1.0 / tmp);
}

const double INF = 1000;

bool contain(const polygon& p, const point& a) {
	const int n = p.size();
	vector<point> vec;
	vec.push_back(a);
	segment scan(point(-INF, a.y), point(INF, a.y));
	for(int i = 0; i < n; ++i) {
		const segment s(p[i], p[(i + 1) % n]);
		if(intersect(scan, s))
			vec.push_back(crosspoint(scan, s));
	}

	if(vec.size() < 3)
		return false;

	sort(vec.begin(), vec.end());
	for(int i = 0; i < (int)vec.size(); ++i)
		if(vec[i] == a)
			return i & 1;
}


int main() {
    double x1, y1, x2, y2, x3, y3, xp, yp;

	while(scanf("%lf %lf %lf %lf %lf %lf %lf %lf",
				&x1, &y1, &x2, &y2, &x3, &y3, &xp, &yp) == 8) {
		polygon p;
		p.push_back(point(x1, y1));
		p.push_back(point(x2, y2));
		p.push_back(point(x3, y3));
		puts(contain(p, point(xp, yp)) ? "YES" : "NO");
	}


	return EXIT_SUCCESS;
}

C++: #include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>
using namespace std;


bool same_side(double x1, double y1, double x2, double y2, double x, double y, double x0, double y0) {
  return ((y1 - y2) * (x - x2) - (x1 - x2) * (y - y2)) * ((y1 - y2) * (x0 - x2) - (x1 - x2) * (y0 - y2)) >= 0;
}

int main() {
  // ifstream cin("../test.txt");
  double x1, y1, x2, y2, x3, y3, xp, yp;
  while (cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> xp >> yp) {
    if (same_side(x1,y1,x2,y2,xp,yp,x3,y3) && same_side(x2,y2,x3,y3,xp,yp,x1,y1) && same_side(x3,y3,x1,y1,xp,yp,x2,y2)) {
      cout << "YES" << endl;
    } else {
      cout << "NO" << endl;
    }
  }
}

C++: #include <iostream>
using namespace std;

struct TCoordinate
{
	double x;
	double y;
};

bool IsSameSide(TCoordinate T1, TCoordinate T2, TCoordinate L1, TCoordinate L2)
{
	double CrossProductT1 = (L2.x - L1.x) * (T1.y - L1.y) - (L2.y - L1.y) * (T1.x - L1.x);
	double CrossProductT2 = (L2.x - L1.x) * (T2.y - L1.y) - (L2.y - L1.y) * (T2.x - L1.x);
	if(CrossProductT1 * CrossProductT2 > 0){
		return true;
	}else{
		return false;
	}
}

int main()
{
	while(true){
		TCoordinate A1, A2, A3, Ap;
		cin >> A1.x >> A1.y >> A2.x >> A2.y >> A3.x >> A3.y >> Ap.x >> Ap.y;
		if(cin.eof() == true) break;
		if(IsSameSide(A3, Ap, A1, A2) && IsSameSide(A1, Ap, A2, A3) && IsSameSide(A2, Ap, A3, A1)){
			cout << "YES" << endl;
		}else{
			cout << "NO" << endl;
		}
	}
	return 0;
}

C++: #include <iostream>
#include <cmath>

using namespace std;

#define v2d Vector2D

struct Vector2D	{
	double x, y;
};

Vector2D sub_vector2D(const Vector2D& a, const Vector2D& b) {
	Vector2D ret;
	ret.x = a.x - b.x; ret.y = a.y - b.y;
	return ret;
}

double out_mul(v2d a, v2d b) {
	return a.x*b.y - a.y*b.x;
}

bool point_in_triangle_2D(v2d a, v2d b, v2d c, v2d p) {
	v2d ab = sub_vector2D(b, a);
	v2d bp = sub_vector2D(p, b);
	
	v2d bc = sub_vector2D(c, b);
	v2d cp = sub_vector2D(p, c);
	
	v2d ca = sub_vector2D(a, c);
	v2d ap = sub_vector2D(p, a);
	
	double c1 = out_mul(ab, bp), c2 = out_mul(bc, cp), c3 = out_mul(ca, ap);
	
	if ( (c1>0 && c2>0 && c3>0) || (c1<0 && c2<0 && c3<0) ) return true;
	return false;
}

int main() {
	v2d a, b, c, p;
	
	while (cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y >> p.x >> p.y) {
		if (point_in_triangle_2D(a, b, c, p)) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	
	return 0;
}