J, 40 39 34 octets
3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-
Une fonction dyadique anonyme, prenant un point, p , comme l'un de ses arguments, et une liste de points, P , comme l'autre argument (peu importe quel argument est lequel), et renvoyant 0
ou 1
, si p est à l'extérieur ou à l'intérieur de la coque convexe de P , respectivement. Le point p et les points de P sont considérés comme des nombres complexes.
Exemple
is_inside =: 3 :'(o.1)<(>./-<./)12 o.y*+{.y'@:-
0.5j0.5 is_inside 0j0 0j1 1j0 1j1
1
1.5j0.5 is_inside 0j0 0j1 1j0 1j1
0
ou...
Python 2, fonction, 121 103, programme complet, 162
Python 3, 149 octets
import sys,cmath as C
p,q,*P=[complex(*eval(l.replace(*";,")))for l in sys.stdin]
A=[C.phase((r-p)/(q-p+(q==p)))for r in P]
print(max(A)-min(A)>C.pi)
Prend l'entrée, dans le même format que le message d'origine, via STDIN, et imprime une valeur booléenne indiquant si p est dans la coque convexe de P
Explication
Le programme teste si la différence entre les angles maximum et minimum (signés) entre tout point r dans P , p et un point arbitraire fixe q dans P (nous utilisons simplement le premier point dans P ), est inférieure à 180 °. En d'autres termes, il teste si tous les points de P sont contenus dans un angle de 180 ° ou moins, autour de p .
p est dans la coque convexe de P si et seulement si cette condition est fausse.
Au prix de quelques octets supplémentaires, nous pouvons utiliser une méthode similaire qui ne nous oblige pas à calculer explicitement les angles: Notez que la condition ci-dessus équivaut à dire que p est en dehors de la coque convexe de P si et seulement s'il existe une ligne l à p , de telle sorte que tous les points de P soient du même côté de l . Si une telle ligne existe, alors il y a aussi une telle ligne qui est incidente à un (ou plusieurs) des points de P (nous pouvons faire pivoter l jusqu'à ce qu'elle touche l'un des points de P ).
Pour (provisoirement) trouver cette ligne, nous commençons par laisser l être la ligne par p et le premier point P . Nous répétons ensuite le reste des points de P ; si l'un des points est à gauche de l (nous supposons que la directionnalité est partout, gauche ou droite n'a pas vraiment d'importance), nous remplaçons l par la ligne passant par p et ce point, et continuons. Après avoir itéré sur tout P , si (et seulement si) p est en dehors de la coque convexe, alors tous les points de P devraient être à droite de (ou sur) l . On vérifie qu'en utilisant un deuxième passage sur les points de P.
Python 2, 172 octets
import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=reduce(lambda*x:x[C(*x)],P)
print any(C(l,q)for q in P)
Alternativement, pour faire la même chose en une seule passe, soit à gauche une représentation entre deux points quelconques, q et r , dans P , de telle sorte que q soit à gauche de r si q est à gauche de la ligne passant par p et r . On notera que to-the-gauche-de est une relation d'ordre sur P si et seulement si tous les points P sont du même côté d' une partie droite passant par p , qui est, si p est en dehors de l'enveloppe convexe de P . La procédure décrite ci-dessus trouve le point minimum dans Ppar rapport'a cet ordre, à savoir la « gauche » point P . Au lieu d'effectuer deux passes, nous pouvons trouver le maximum (c'est-à-dire, le point "le plus à droite"), ainsi que le minimum, les points en P par rapport au même ordre en une seule passe, et vérifier que le minimum est à gauche de la maximum, c'est-à-dire effectivement que celui de gauche est transitif.
Cela fonctionnerait bien si p est en dehors de la coque convexe de P , auquel cas à gauche est en fait une relation d'ordre, mais peut se casser lorsque p est à l'intérieur de la coque convexe (par exemple, essayez de comprendre ce qui va arriver si nous avons exécuté cet algorithme où les points dans P sont les sommets d'un pentagone régulier, dans le sens inverse des aiguilles d'une montre, et p est son centre.) Pour s'adapter, nous modifions légèrement l'algorithme: Nous sélectionnons un point q dans P , et bissectons P le long de la ligne passant par p et q (c'est-à-dire que nous partitionnons P autour de qpar rapport à gauche.) Nous avons maintenant une "partie gauche" et une "partie droite" de P , chacune contenue dans un demi-plan, de sorte que à gauche est une relation d'ordre sur chacune; nous trouvons le minimum de la partie gauche et le maximum de la partie droite et les comparons comme décrit ci-dessus. Bien sûr, nous n'avons pas à diviser physiquement P , nous pouvons simplement classer chaque point dans P en recherchant le minimum et le maximum, en une seule passe.
Python 2, 194 octets
import sys
P=[eval(l.replace(*";,"))for l in sys.stdin]
x,y=P.pop(0)
C=lambda(a,b),(c,d):(a-x)*(d-y)-(b-y)*(c-x)>0
l=r=P[0]
for q in P:
if C(P[0],q):l=q*C(l,q)or l
elif C(q,r):r=q
print C(l,r)