Periksa apakah titik terletak di dalam segitiga

40

Tujuan Anda adalah untuk menentukan apakah titik 2D X yang diberikan terletak di dalam area segitiga dengan simpul A, B, C yang diberikan.

Tulis fungsi yang mengambil dalam koordinat titik uji X dan tiga simpul segitiga (jadi total koordinat 8) dan mengembalikan True jika titik terletak di dalam segitiga itu, dan Salah jika terletak di luar.

Jangan khawatir tentang tepi kasus. Jika titik terletak pada batas segitiga (tepi atau dhuwur) atau segitiga sebenarnya merupakan segmen garis, kode Anda dapat melakukan apa saja, termasuk menabrak. Juga jangan khawatir tentang stabilitas numerik atau presisi floating-point.

Kode Anda harus berupa fungsi bernama. Cuplikan kode tidak akan diterima.

Karakter yang paling sedikit menang.

Memasukkan:

Delapan bilangan real mewakili koordinat. Angka-angka akan berada dalam kisaran (-1,1).

Format input yang tepat fleksibel. Anda dapat, misalnya, mengambil dalam delapan angka, daftar delapan angka, daftar empat poin yang masing-masing diberikan oleh sebuah tuple, sebuah matriks 2 * 4, empat angka kompleks, dua daftar koordinat x dan koordinat y, dan seterusnya.

Masukan harus berupa angka-angka dalam wadah, tanpa data tambahan. Anda tidak dapat menggunakan input untuk melakukan preprocessing apa pun, Anda juga mungkin tidak memerlukan kendala pada input, seperti mengharuskan poin diberikan dalam koordinat naik y. Input Anda harus mengizinkan delapan koordinat (meskipun kode Anda dapat berperilaku sewenang-wenang dalam kasus tepi yang disebutkan sebelumnya).

Harap sebutkan format input Anda.

Keluaran:

Baik Boolean yang sesuai True/ False, nomor yang sesuai 1/ 0, atau analog dalam bahasa Anda.

Uji kasus

Input diberi daftar [X,A,B,C]empat tupel, titik uji pertama, lalu tiga simpul segitiga. Saya telah mengelompokkan mereka ke dalam output yang seharusnya Truedan yang seharusnya False.

True contoh:

[(-0.31961, -0.12646), (0.38478, 0.37419), (-0.30613, -0.59754), (-0.85548, 0.6633)]
[(-0.87427, -0.00831), (0.78829, 0.60409), (-0.90904, -0.13856), (-0.80685, 0.48468)]
[(0.28997, -0.03668), (-0.28362, 0.42831), (0.39332, -0.07474), (-0.48694, -0.10497)]
[(-0.07783, 0.04415), (-0.34355, -0.07161), (0.59105, -0.93145), (0.29402, 0.90334)]
[(0.36107, 0.05389), (0.27103, 0.47754), (-0.00341, -0.79472), (0.82549, -0.29028)]
[(-0.01655, -0.20437), (-0.36194, -0.90281), (-0.26515, -0.4172), (0.36181, 0.51683)]
[(-0.12198, -0.45897), (-0.35128, -0.85405), (0.84566, 0.99364), (0.13767, 0.78618)]
[(-0.03847, -0.81531), (-0.18704, -0.33282), (-0.95717, -0.6337), (0.10976, -0.88374)]
[(0.07904, -0.06245), (0.95181, -0.84223), (-0.75583, -0.34406), (0.16785, 0.87519)]
[(-0.33485, 0.53875), (-0.25173, 0.51317), (-0.62441, -0.90698), (-0.47925, 0.74832)]

False contoh:

[(-0.99103, 0.43842), (0.78128, -0.10985), (-0.84714, -0.20558), (-0.08925, -0.78608)]
[(0.15087, -0.56212), (-0.87374, -0.3787), (0.86403, 0.60374), (0.01392, 0.84362)]
[(0.1114, 0.66496), (-0.92633, 0.27408), (0.92439, 0.43692), (0.8298, -0.29647)]
[(0.87786, -0.8594), (-0.42283, -0.97999), (0.58659, -0.327), (-0.22656, 0.80896)]
[(0.43525, -0.8923), (0.86119, 0.78278), (-0.01348, 0.98093), (-0.56244, -0.75129)]
[(-0.73365, 0.28332), (0.63263, 0.17177), (-0.38398, -0.43497), (-0.31123, 0.73168)]
[(-0.57694, -0.87713), (-0.93622, 0.89397), (0.93117, 0.40775), (0.2323, -0.30718)]
[(0.91059, 0.75966), (0.60118, 0.73186), (0.32178, 0.88296), (-0.90087, -0.26367)]
[(0.3463, -0.89397), (0.99108, 0.13557), (0.50122, -0.8724), (0.43385, 0.00167)]
[(0.88121, 0.36469), (-0.29829, 0.21429), (0.31395, 0.2734), (0.43267, -0.78192)]
Tidak
sumber
Apa definisi Anda tentang karakter? Ascii? Dikodekan dalam 7 bit? Dalam satu byte? Ada Unicode?
isaacg
Apa yang Anda sarankan? Sudah ada solusi yang menggunakan kode terkompresi.
xnor
Biasanya, saya percaya byte digunakan untuk karakter non-Ascii, karena jika tidak, keunggulan Utf-32 tidak dapat diatasi.
isaacg
Yah, aku tidak bisa kembali sekarang; setiap karakter Unicode adalah sebuah karakter. Kompres jika Anda mau.
xnor

Jawaban:

19

Javascript / ECMAScript 6, 161 159 158/152

Javascript:

function $(t,r,i,a,n,g,l,e){b=(-g*l+a*(-n+l)+i*(g-e)+n*e)/2;c=b<0?-1:1;d=(a*l-i*e+(e-a)*t+(i-l)*r)*c;f=(i*g-a*n+(a-g)*t+(n-i)*r)*c;return d>0&&f>0&&d+f<2*b*c}

Versi ECMAScript 6 (terima kasih m.buettner, hemat 6 karakter)

$=(t,r,i,a,n,g,l,e)=>{b=(-g*l+a*(-n+l)+i*(g-e)+n*e)/2;c=b<0?-1:1;d=(a*l-i*e+(e-a)*t+(i-l)*r)*c;f=(i*g-a*n+(a-g)*t+(n-i)*r)*c;return d>0&&f>0&&d+f<2*b*c}

Sebut saja (mengembalikan trueatau false):

$(pointX, pointY, v1X, v1Y, v2X, v2Y, v3X, v3Y);

Menggunakan beberapa matematika koordinat barycentric yang mewah berdasarkan kode dari jawaban ini . Versi ungolfed untuk kesenangan membaca Anda mengikuti:

function $ (pointX, pointY, v1X, v1Y, v2X, v2Y, v3X, v3Y) {
  var A =  (-v2Y * v3X + v1Y * (-v2X + v3X) + v1X * (v2Y - v3Y) + v2X * v3Y) / 2;
  var sign = A < 0 ? -1 : 1;
  var s = (v1Y * v3X - v1X * v3Y + (v3Y - v1Y) * pointX + (v1X - v3X) * pointY) * sign;
  var t = (v1X * v2Y - v1Y * v2X + (v1Y - v2Y) * pointX + (v2X - v1X) * pointY) * sign;
  return s > 0 && t > 0 && s + t < 2 * A * sign;
}
Abraham
sumber
12
+1, jika hanya untuk nama parameter!
Matt
Mengapa Anda harus memecahkan UserScript penghitungan karakter saya ???
kitcar2000
@ kitcar2000 apa maksudmu?
Abraham
Aturan mengatakan bahwa karakter dihitung, bukan byte. Jadi Anda dapat menggunakan ini: xem.github.io/obfuscatweet agar sesuai dengan 122 karakter
xem
1
Apakah saya salah, atau bisakah Anda menggunakan (a*(l-n)+i*(g-e)+n*e-g*l)alih-alih (-g*l+a*(-n+l)+i*(g-e)+n*e)?
Zacharý
19

Python 2.7 128 127 117 110 109 103 99 95 94 91 90

Usaha kode-golf pertama saya!

Kode

f=lambda x,y,t:sum(a*y+c*b+d*x<d*a+c*y+b*x for i in(0,1,2)for a,b,c,d in[t[i-1]+t[i]])%3<1

Dibawa sebagai input (x, y, t) di mana (x, y) adalah titik yang kami periksa dan t adalah segitiga t = ((x1, y1), (x2, y2), (x3, y3)).

Penjelasan

Saya menghitung faktor penentu dari matriks

| 1 x1 y1 |      | 1 x2 y2 |      | 1 x3 y3 |
| 1 x2 y2 | ,    | 1 x3 y3 | ,    | 1 x1 y1 | .
| 1 x  y  |      | 1 x  y  |      | 1 x  y  |

Penentu ini mewakili jarak yang ditandatangani dari sisi segitiga ke titik (x, y). Jika mereka semua memiliki tanda yang sama, maka titiknya berada di sisi yang sama dari setiap garis dan dengan demikian terkandung dalam segitiga.

Dalam kode di atas, a*y+c*b+d*x-d*a-c*y-b*xmerupakan penentu salah satu dari matriks ini.

Saya menggunakan fakta itu True+True+True==3dan False+False+False==0untuk menentukan apakah semua penentu ini memiliki tanda yang sama.

Saya menggunakan indeks daftar negatif Python dengan menggunakan t[-1]alih-alih t[(i+1)%3].

Terima kasih Peter atas ide untuk digunakan s%3<1daripada s in(0,3)memeriksa apakah s adalah 0 atau 3!

Versi Sagemath

Tidak benar-benar solusi yang berbeda jadi saya memasukkannya dalam jawaban ini, solusi sagemath menggunakan 80 karakter:

f=lambda p,t,o=[1]:sum([det(Matrix([o+t[i-1],o+t[i],o+p]))<0for i in 0,1,2])%3<1

dimana p=[x,y], dant=[[x1,y1],[x2,y2],[x3,y3]]

Alex L
sumber
1
Bisa s in (0,3)disingkat menjadi s%3<1?
Peter Taylor
1
Penggunaan indeks negatif dapat diubah untuk menghemat satu lagi: -1,0,1 ... t[i]+t[i+1]setara dengan0,1,2 ... t[i-1]+t[i]
Peter Taylor
@PeterTaylor Benar sekali! Sayang sekali saya menghapus spasi in -1,0,1sebelum membaca ini. Sebenarnya cara Anda lebih mudah dibaca jadi saya tetap akan menggunakannya.
Alex L
1
Selamat datang di kode golf! Anda dapat menyingkirkan tanda kurung persegi untuk daftar pemahaman dalam sumjika Anda menyelimuti 0,1,2dalam kurung, hal karakter dengan mengganti spasi. Alasannya adalah bahwa Python memungkinkan pemahaman unbracketed untuk diteruskan ke fungsi, tetapi koma dalam tuple telanjang 1,2,3membingungkannya karena mencoba mengurai mereka sebagai argumen terpisah.
xnor
16

Mathematica, 67 byte

f=Equal@@({#2,-#}&@@(#-#2).(x-#)>0&@@@Partition[x=#;#2,2,1,{1,1}])&

Fungsi ini mengambil dua argumen, titik Xdan daftar titik {A,B,C}, yang disebut masing #- #2masing. Itu jika Anda menelepon

f[X,{A,B,C}]

maka Anda akan mendapatkan #sebagai Xdan #2sebagai {A,B,C}. (Perhatikan bahwa ada dua fungsi anonim lainnya yang bersarang di dalam kode - #dan #2memiliki arti berbeda di dalamnya.)

Berikut ini penjelasan fungsi itu sendiri:

                                              x=#;#2            & (* Save X into a variable x, but evaluate to {A,B,C}. *)
                                    Partition[x=#;#2,2,1,{1,1}] & (* Get a cyclic list of pairs {{A,B},{B,C},{C,B}}. *)
       (                        &@@@Partition[x=#;#2,2,1,{1,1}])& (* Define an anonymous function and apply it to each 
                                                                     of the above pairs. The two elements are referred 
                                                                     to as # and #2. *)
       (          (#-#2)        &@@@Partition[x=#;#2,2,1,{1,1}])& (* Subtract the two points. For a pair of vertices 
                                                                     this yields a vector corresponding to the edge 
                                                                     between them. *)
        {#2,-#}&                                                  (* An anonymous function that takes two values, 
                                                                     reverses them, inverts the sign of one of them 
                                                                     and puts them into a list. *)
       ({#2,-#}&@@(#-#2)        &@@@Partition[x=#;#2,2,1,{1,1}])& (* Applied to the edge, this yields its normal. *)
       ({#2,-#}&@@(#-#2).(x-#)  &@@@Partition[x=#;#2,2,1,{1,1}])& (* Take the scalar product of that normal with a
                                                                     vector from a vertex to x. This is projection of 
                                                                     this vector onto that normal and hence the SIGNED
                                                                     distance of x from the edge. *)
       ({#2,-#}&@@(#-#2).(x-#)>0&@@@Partition[x=#;#2,2,1,{1,1}])& (* Check the sign of that distance, the exact mapping 
                                                                     between (left, right) and (True, False) is 
                                                                     irrelevant, as long as it's consistent. *)
Equal@@({#2,-#}&@@(#-#2).(x-#)>0&@@@Partition[x=#;#2,2,1,{1,1}])& (* Check if all signs are equal - that is, if point X 
                                                                     lies on the same side of all edges. This is 
                                                                     equivalent to check that the point is inside the 
                                                                     triangle. *)

Perhatikan bahwa fungsi ini akan benar-benar bekerja untuk setiap cembung n-gon selama simpul diberikan baik searah jarum jam atau berlawanan arah jarum jam order.

Martin Ender
sumber
Bukankah lebih efisien untuk memeriksa apakah produk dari jaraknya positif daripada jika semua tanda sama? Saya tidak Mathematica, tetapi sepertinya itu seharusnya lebih mudah.
isaacg
@isaacg Ada tiga istilah, jadi jika semuanya negatif, produknya negatif dan jika semuanya positif, produknya positif. Pendekatan Anda hanya bekerja jika tanda-tanda dua angka harus sama.
Martin Ender
Kenapa tidak digunakan Det?
alephalpha
@alephalpha Yah, kemungkinan besar karena saya tidak memikirkannya. : P ... Saya akan memeriksanya
Martin Ender
@alephalpha Hm tidak, saya tidak dapat menemukan cara sekarang untuk membangun tiga matriks yang diperlukan dalam karakter yang lebih sedikit.
Martin Ender
7

CJam, 66 63 59 52 46 34 32 31 30 28 karakter

"Ă䒟损崙㩴ァ椟饃꿾藭鑭蘁"2G#b131b:c~

Setelah mengubah string Unicode, kode berikut ( 33 byte ) akan dievaluasi:

{2*2/\f{f{+~@-@@-}~@@*@@*>})-!}:T

Diharapkan X [A B C]sebagai input, di mana setiap titik dalam formulir [double double]. Outputnya 1 atau 0.

Cobalah online.

Terima kasih banyak kepada user23013 untuk menyimpan 6 karakter (13 byte kode terkompresi)!

Uji kasus

$ cat triangle.cjam
"Ă䒟损崙㩴ァ椟饃꿾藭鑭蘁"2G#b131b:c~

[
  [-0.31961 -0.12646] [ [0.38478 0.37419]   [-0.30613 -0.59754] [-0.85548 0.6633]   ] T
  [-0.87427 -0.00831] [ [0.78829 0.60409]   [-0.90904 -0.13856] [-0.80685 0.48468]  ] T
  [0.28997 -0.03668]  [ [-0.28362 0.42831]  [0.39332 -0.07474]  [-0.48694 -0.10497] ] T
  [-0.07783 0.04415]  [ [-0.34355 -0.07161] [0.59105 -0.93145]  [0.29402 0.90334]   ] T
  [0.36107 0.05389]   [ [0.27103 0.47754]   [-0.00341 -0.79472] [0.82549 -0.29028]  ] T
  [-0.01655 -0.20437] [ [-0.36194 -0.90281] [-0.26515 -0.4172]  [0.36181 0.51683]   ] T
  [-0.12198 -0.45897] [ [-0.35128 -0.85405] [0.84566 0.99364]   [0.13767 0.78618]   ] T
  [-0.03847 -0.81531] [ [-0.18704 -0.33282] [-0.95717 -0.6337]  [0.10976 -0.88374]  ] T
  [0.07904 -0.06245]  [ [0.95181 -0.84223]  [-0.75583 -0.34406] [0.16785 0.87519]   ] T
  [-0.33485 0.53875]  [ [-0.25173 0.51317]  [-0.62441 -0.90698] [-0.47925 0.74832]  ] T
  [-0.99103 0.43842]  [ [0.78128 -0.10985]  [-0.84714 -0.20558] [-0.08925 -0.78608] ] T
  [0.15087 -0.56212]  [ [-0.87374 -0.3787]  [0.86403 0.60374]   [0.01392 0.84362]   ] T
  [0.1114 0.66496]    [ [-0.92633 0.27408]  [0.92439 0.43692]   [0.8298 -0.29647]   ] T
  [0.87786 -0.8594]   [ [-0.42283 -0.97999] [0.58659 -0.327]    [-0.22656 0.80896]  ] T
  [0.43525 -0.8923]   [ [0.86119 0.78278]   [-0.01348 0.98093]  [-0.56244 -0.75129] ] T
  [-0.73365 0.28332]  [ [0.63263 0.17177]   [-0.38398 -0.43497] [-0.31123 0.73168]  ] T
  [-0.57694 -0.87713] [ [-0.93622 0.89397]  [0.93117 0.40775]   [0.2323 -0.30718]   ] T
  [0.91059 0.75966]   [ [0.60118 0.73186]   [0.32178 0.88296]   [-0.90087 -0.26367] ] T
  [0.3463 -0.89397]   [ [0.99108 0.13557]   [0.50122 -0.8724]   [0.43385 0.00167]   ] T
  [0.88121 0.36469]   [ [-0.29829 0.21429]  [0.31395 0.2734]    [0.43267 -0.78192]  ] T
]p;

$ cjam triangle.cjam
[1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
Dennis
sumber
Apakah itu fungsi yang dinamai?
Martin Ender
@ m.buettner: Semacam. The wiki resmi mengatakan berikut: Blok - bagian program yang dibatasi oleh {dan }dan diperlakukan sebagai satu kesatuan. Mirip dengan blok kode dalam C / java, kecuali blok adalah objek kelas satu dan dapat ditugaskan ke variabel (dengan demikian mendefinisikan fungsi).
Dennis
1
@xnor 1m<@m*menyiapkan 3 pasang X dan i+1simpul ( th) segitiga berikutnya. @-@@-memindahkan titik ( ith) saat ini ke titik asal (dan mencerminkan jika tidak @-\@-, tetapi tidak masalah). @@*@@*>menghitung sumbu z dari produk silang, alias determinan, dan mengembalikan 1jika negatif. :+3%!mengembalikan apakah mereka semua sama, yaitu, ketiga adalah negatif atau non-negatif, yang berarti positif kecuali untuk kasus tepi. Saya pikir lebih sulit membaca CJam daripada bermain golf.
jimmy23013
1
37 byte: {[_1m<\]z\f{f{+~@-@@-}~@@*@@*>})-!}:T. Gunakan 2m>atau Wm<untuk keamanan Unicode.
jimmy23013
1
33 byte:{2*2/\f{f{+~@-@@-}~@@*@@*>})-!}:T
jimmy23013
5

C - 156 byte

Input adalah larik 3 float di X, 3 float di Y dan pisahkan x dan y untuk titik uji. Bonus: menangani semua kasus tepi!

int f(float*X,float*Y,float x,float y){int i,j,c=0;for(i=0,j=2;i<3;j=i++)if(((Y[i]>y)!=(Y[j]>y))&&(x<(X[j]-X[i])*(y-Y[i])/(Y[j]-Y[i])+X[i]))c=!c;return c;}

Diadaptasi dari PNPOLY.


sumber
i;j;c;f(float*X,float*Y,float x,float y){for(c=i=0,j=2;i<3;)c^=(Y[i]>y)-(Y[j]>y)&(x<(X[j]-X[i])*(y-Y[i])/(Y[j]-Y[i])+X[j=i++]);return c;}137 - diuji dalam javascript
bebe
@ Bebe - Itu menyebabkan kesalahan sintaks.
Derek 朕 會 功夫
Itu tidak menyebabkan kesalahan sintaksis.
bebe
4

Pyth 1.0.5 , 57 54 51

DgYb=Z0J'bWbK;bDiHNR*-'H'K-@N1@K1~Z>iYJiJY=JK)R!%Z3

Menentukan fungsi g, yang mengambil dua input: titik uji, dan kemudian daftar simpul segitiga. Output Truedan False. Catatan: Hancurkan input, khususnya b, daftar simpul segitiga.

Coba di sini . Beberapa karakter terakhir, gvwvwpanggil fungsi dengan case uji pada dua baris berikutnya.

Berdasarkan algoritma ini

Penjelasan:

DgYb                  Define g(Y,b):
=Z0                     Z=0
J'b                     J=b[0]              (No = is needed because j is special).
Wb                      While len(b)>0:     (While b:)
K;b                       K=b.pop()
DiHN                      Define i(H,N):    
R*-'H'K-@N1@K1              Return half of the linked equation.
~ZiYJiJY                  Z+=i(Y,J)>i(J,Y)
=JK                       J=K
)                       Wend
R!%Z3                   return not Z%3==0   (True iff Z == 0 or 3)

Perang CJam - Pyth mengamuk terus!

isaacg
sumber
Ini harus berupa fungsi bernama. Apakah wmengambil input STDIN?
xnor
@ xnor Ups, saya melewatkan deskripsi itu. Akan diedit.
isaacg
@xnor Apakah fungsi yang mencetak jawaban dibolehkan, atau haruskah mereka mengembalikan jawabannya? Saat ini, ini mencetak jawabannya, tetapi saya bisa mengembalikannya untuk satu karakter lagi.
isaacg
Kembalikan jawabannya.
xnor
Bisakah Anda menyimpan karakter dengan mengganti penghitung Zdengan set kosong yang Anda kumpulkan Z|=, lalu menguji panjangnya untuk melihat apakah hanya 0atau 1hanya terlihat? Strateginya ternyata lebih lama dalam Python, tapi mungkin itu layak menggunakan primitif Pyth.
xnor
4

J 64 45 (42 tanpa tugas)

c=:*./@(>:&0)@({.(,(1-+/))@%.|:@}.)@(}:-"1{:)

Penugasan tidak diperlukan untuk hal yang akan berfungsi, jadi tidak yakin apakah akan menghitungnya atau tidak. Mengambil keuntungan dari input fleksibel: Saya ingin memiliki array (1 + jumlah simpul) x (dimensi ruang).

Berharap untuk mencetak beberapa poin tambahan di sini ...: Benda ini berfungsi untuk semua dimensi simpleks, tidak hanya segitiga dalam pesawat, tetapi juga piramida 3 sisi dalam ruang 3d dan sebagainya. Ia juga bekerja ketika jumlah simpul simpleks lebih kecil dari (n +1), maka ia menghitung apakah proyeksi titik ke simpleks berada di dalam atau tidak.

Itu mengkonversi ke koordinat barycentric , kemudian memeriksa yang negatif, menunjukkan titik di luar. Apakah pikiran J menggunakan _ untuk negatif

NB. example in triangle
D =: 4 2 $ 1 1 0 0 3 0 0 2 NB. 4 rows , x first, then the vertices of the triangle

NB. subtract last vertex coordinates from the rest and drop reference node
n=: (}:-"1{:)

NB. preprocessed to barycentric coordinates
bar=: {. (, 1 - +/)@%. |:@}.

NB. all positive
ap =: *./@(>:&0)

insided =: ap@bar@n

inside D
1

Jalankan pada contoh yang diberikan:

   true =: 0 : 0
[(-0.31961, -0.12646), (0.38478, 0.37419), (-0.30613, -0.59754), (-0.85548, 0.6633)]
[(-0.87427, -0.00831), (0.78829, 0.60409), (-0.90904, -0.13856), (-0.80685, 0.48468)]
[(0.28997, -0.03668), (-0.28362, 0.42831), (0.39332, -0.07474), (-0.48694, -0.10497)]
[(-0.07783, 0.04415), (-0.34355, -0.07161), (0.59105, -0.93145), (0.29402, 0.90334)]
[(0.36107, 0.05389), (0.27103, 0.47754), (-0.00341, -0.79472), (0.82549, -0.29028)]
[(-0.01655, -0.20437), (-0.36194, -0.90281), (-0.26515, -0.4172), (0.36181, 0.51683)]
[(-0.12198, -0.45897), (-0.35128, -0.85405), (0.84566, 0.99364), (0.13767, 0.78618)]
[(-0.03847, -0.81531), (-0.18704, -0.33282), (-0.95717, -0.6337), (0.10976, -0.88374)]
[(0.07904, -0.06245), (0.95181, -0.84223), (-0.75583, -0.34406), (0.16785, 0.87519)]
[(-0.33485, 0.53875), (-0.25173, 0.51317), (-0.62441, -0.90698), (-0.47925, 0.74832)]
)

   false =: 0 : 0
[(-0.99103, 0.43842), (0.78128, -0.10985), (-0.84714, -0.20558), (-0.08925, -0.78608)]
[(0.15087, -0.56212), (-0.87374, -0.3787), (0.86403, 0.60374), (0.01392, 0.84362)]
[(0.1114, 0.66496), (-0.92633, 0.27408), (0.92439, 0.43692), (0.8298, -0.29647)]
[(0.87786, -0.8594), (-0.42283, -0.97999), (0.58659, -0.327), (-0.22656, 0.80896)]
[(0.43525, -0.8923), (0.86119, 0.78278), (-0.01348, 0.98093), (-0.56244, -0.75129)]
[(-0.73365, 0.28332), (0.63263, 0.17177), (-0.38398, -0.43497), (-0.31123, 0.73168)]
[(-0.57694, -0.87713), (-0.93622, 0.89397), (0.93117, 0.40775), (0.2323, -0.30718)]
[(0.91059, 0.75966), (0.60118, 0.73186), (0.32178, 0.88296), (-0.90087, -0.26367)]
[(0.3463, -0.89397), (0.99108, 0.13557), (0.50122, -0.8724), (0.43385, 0.00167)]
[(0.88121, 0.36469), (-0.29829, 0.21429), (0.31395, 0.2734), (0.43267, -0.78192)]
)
   NB. replace - by _ to avoid problems
   NB. cut up per row, drop the [ ] and convert to numbers
   $dat_t =: ((4 2 $ ".)@}:@}.;._2) (true='-')} true ,: '_'
10 4 2
   $dat_f =: ((4 2 $ ".)@}:@}.;._2) (false='-')}false,: '_'
10 4 2
   NB. this results in arrays with shape 10 4 2

   NB. for each 4 x 2 array (rank 2), do c for all true instances
   c=:*./@(>:&0)@({.(,(1-+/))@%.|:@}.)@(}:-"1{:)
   c"2 dat_t
1 1 1 1 1 1 1 1 1 1
   NB. the same for the false ones, demonstrating anonymous usage
   NB. still a function though (or verb in J parlance)
   *./@(>:&0)@({.(,(1-+/))@%.|:@}.)@(}:-"1{:)"2 dat_f
0 0 0 0 0 0 0 0 0 0
jpjacobs
sumber
Saya meminta fungsi bernama, sehingga karakter tugas dihitung. Berikut adalah beberapa poin untuk menggeneralisasi ke poligon! ······
xnor
Sebenarnya, saya tidak terlalu menyamaratakan dengan poligon, tetapi untuk simpleks dimensi-N, dengan N+1simpul maksimum . Misalnya 4 vertex pyramid dalam ruang 3-D, atau 5 vertex simplex dalam ruang 4-D. Jumlah simpul bisa lebih rendah daripada N+1, dalam hal ini algoritma melihat apakah proyeksi ortogonal ke hyperplane tempat simpleks berada di dalam simpleks atau tidak (misalnya simpleks 2 titik dalam 2-D akan diproyeksikan pada garis dan diperiksa) apakah proyeksi ini terletak di antara titik akhir)
jpjacobs
4

HTML5 + JS, 13b + 146b / 141b / 114 karakter

HTML:

<canvas id=C>

JS (146b):

// @params: t1x, t1y, t2x, t2y, t3x, t3y, pointx, pointy
function T(a,b,c,d,e,f,g,h){with(C.getContext("2d"))return beginPath(),moveTo(a,b),lineTo(c,d),lineTo(e,f),fill(),!!getImageData(g,h,1,1).data[3]}

atau ES6 (141b):

T=(a,b,c,d,e,f,g,h)=>{with(C.getContext("2d"))return beginPath(),moveTo(a,b),lineTo(c,d),lineTo(e,f),fill(),!!getImageData(g,h,1,1).data[3]}

atau ES6 unicode-obfuscated (114 chars):

eval(unescape(escape('𥀽𚁡𛁢𛁣𛁤𛁥𛁦𛁧𛁨𚐽🡻𭱩𭁨𚁃𛡧𩑴𠱯𫡴𩑸𭀨𘠲𩀢𚐩𬡥𭁵𬡮𘁢𩑧𪑮𤁡𭁨𚀩𛁭𫱶𩑔𫰨𨐬𨠩𛁬𪑮𩑔𫰨𨰬𩀩𛁬𪑮𩑔𫰨𩐬𩠩𛁦𪑬𫀨𚐬𘐡𩱥𭁉𫑡𩱥𡁡𭁡𚁧𛁨𛀱𛀱𚐮𩁡𭁡𦰳𧑽').replace(/uD./g,'')))

demo: http://jsfiddle.net/xH8mV/

Kebingungan Unicode dibuat dengan: http://xem.github.io/obfuscatweet/

xem
sumber
Tampaknya tidak menghasilkan hasil yang benar ketika titik dekat ke samping: jsfiddle.net/L2B2A Saya percaya ini karena semua input berada di antara (-1,1), dan kode Anda hanya menguji 4 piksel sekitar asal.
Derek 朕 會 功夫
itu benar, agar sesuai dengan contoh, saya harus mengubah asal dan skala kanvas saya untuk menangani segitiga di dalam [-1,1]. Tapi mengapa segitiga itu begitu kecil?
xem
masalahnya mengatakan bahwa semua xy adalah antara -1 dan 1. Tidak benar-benar tahu mengapa, tapi saya yakin Anda bisa mengalikan setiap input dengan 1e7 (untuk mempertahankan presisi) bisa mendapatkan hasil yang benar: D
Derek 朕 會 功夫
Solusi grafis, sangat pintar!
xnor
3

Python (65)

Orang-orang sepertinya sudah selesai mengirimkan, jadi saya akan mengirimkan solusi saya sendiri untuk pertanyaan saya.

f=lambda X,L:sum(((L[i-1]-X)/(L[i]-X)).imag>0for i in(0,1,2))%3<1

Xadalah bilangan kompleks yang mewakili titik uji, dan Lmerupakan daftar tiga titik, masing-masing bilangan kompleks.

Pertama, saya akan menjelaskan versi kode yang kurang golf;

def f(X,A,B,C):A-=X;B-=X;C-=X;return((A/B).imag>0)==((B/C).imag>0)==((C/A).imag>0)

Kami menggeser titik-titik A,B,C,Xsehingga Xberada pada titik asal, mengambil keuntungan dari aritmatika kompleks built-in Python. Kita perlu memeriksa apakah sumbernya terkandung dalam lambung cembung A,B,C. Ini setara dengan titik asal yang selalu terletak di sisi yang sama (kiri atau kanan) dari segmen garis AB, BC, dan AC.

Segmen ABmemiliki asal di sebelah kiri jika satu perjalanan berlawanan arah jarum jam kurang dari 180 derajat untuk mendapatkan dari A ke B, dan di sebelah kanan sebaliknya. Jika kita mempertimbangkan sudut a,, bdan csesuai dengan titik-titik ini, ini berarti b-a < 180 degrees(sudut diambil dalam kisaran 0 hingga 360 derajat). Sebagai bilangan kompleks angle(B/A)=angle(B)/angle(A),. Juga, angle(x) < 180 degreestepatnya untuk titik di atas setengah pesawat, yang kami periksa via imag(x)>0.

Jadi apakah asal terletak di sebelah kiri AB dinyatakan sebagai (A/B).imag>0. Memeriksa apakah ini semua sama untuk setiap pasangan siklik di A,B,Cmemberitahu kita apakah segitiga ABCmengandung asal.

Sekarang, mari kita kembali ke kode golf sepenuhnya

f=lambda X,L:sum(((L[i-1]-X)/(L[i]-X)).imag>0for i in(0,1,2))%3<1

Kami menghasilkan setiap pasangan siklik (A-X,B-X,C-X)=(L[0]-X,L[1]-X,L[2]-X), mengambil keuntungan dari indeks daftar Python negatif yang membungkus ( L[-1]= L[2]). Untuk memeriksa apakah Bools adalah semua True( 1) atau semua False( 0), kami menambahkannya dan memeriksa pembagian dengan 3, seperti yang dilakukan banyak solusi.

Tidak
sumber
2

Fortran - 232 218 195 174

Sangat mengerikan. Fungsi ini mengerikan karena persyaratan bahwa data dilewatkan ke sana dan kami tidak dapat memprosesnya.

logical function L(x);real::x(8);p=x(1)-x(3);q=x(2)-x(4);r=x(5)-x(3);s=x(6)-x(4);t=x(7)-x(3);u=x(8)-x(4);L=ALL([p*(s-u)+q*(t-r)+r*u-t*s,p*u-q*t,q*r-p*s]>=r*u-t*s);endfunction

Penurunan 14 karakter adalah karena saya lupa golf nama fungsi dari tes saya berjalan. Penurunan lebih lanjut disebabkan oleh pengetikan tersirat dan lupa untuk mengubah nama fungsi. 20 karakter berikutnya keluar karena membaca dalam poin sebagai array tunggal. Program lengkapnya adalah

program inTriagle
   real, dimension(2) :: a,b,c,x
   do 
      print*,"Enter coordinates as x,a,b,c"
      read*,x,a,b,c
      if(all(x==0.0).and.all(a==0.0).and.all(b==0.0).and.all(c==0.0)) exit
      print*,"Is point in triangle: ",T(x,a,b,c)
   enddo
 contains!                       
   logical function L(x)
     real::x(8)
     p=x(1)-x(3);q=x(2)-x(4);r=x(5)-x(3)
     s=x(6)-x(4);t=x(7)-x(3);u=x(8)-x(4)
     L=ALL([p*(s-u)+q*(t-r)+r*u-t*s,p*u-q*t,q*r-p*s]>=r*u-t*s)
   endfunction
end program inTriagle
Kyle Kanos
sumber
1
Anda dapat membuat ini sedikit lebih pendek dengan mengandalkan pengetikan tersirat Fortran dan menggunakan array input tunggal yang berisi semua 8 angka: logical function T(x);real x(8);p=x(1)-x(3);q=x(2)-x(4);r=x(5)-x(3);s=x(6)-x(4);u=x(7)-x(3);v=x(8)-x(4);o=r*v-u*s;T=ALL([p*(s-v)+q*(u-r)+o,p*v-q*u,q*r-p*s]>=o);endSaya sudah mencoba memperpendek ini lebih lanjut dengan menggunakan operasi daftar, tapi sayangnya itu tidak berhasil dengan baik.
Ventero
1
Bahkan lebih pendek dengan menghilangkan sub-ekspresi yang lebih umum: logical function T(x);real x(8);p=x(1)-x(3);q=x(2)-x(4);r=x(5)-x(3);s=x(6)-x(4);u=x(7)-x(3);v=x(8)-x(4);a=r*v-u*s;b=p*v-q*u;d=q*r-p*s;T=ALL([a-b-d,b,d]>=a);endSaya harap saya tidak membuat kesalahan dalam transformasi! Meskipun sepertinya kode asli Anda tidak lulus semua testcases.
Ventero
@Ventero: Saya tidak percaya saya lupa menyalahgunakan pengetikan implisit :(. Terima kasih atas bantuan Anda!
Kyle Kanos
@Ventero: Juga, sepertinya jawaban saya tergantung pada orientasi segitiga. Contoh pertama Truedalam OP memberikan Falsejika saya menukar Bdan Cnilai sambil memberikan Trueuntuk orientasi asli.
Kyle Kanos
Ah, memang, masalahnya disebabkan ketika (menggunakan kembali notasi dari komentar saya sebelumnya) a < 0, yang secara efektif membalikkan kondisi yang harus Anda uji. Sayangnya ini tidak bisa diperbaiki dengan membungkus segala sesuatu dalam abs, karena kemudian kondisi tersirat bdan dmemiliki tanda yang sama seperti ahilang. Ini dapat diperbaiki dengan menggunakan sesuatu seperti (sekali lagi, menggunakan kembali notasi dan variabel yang telah ditentukan dari komentar terakhir saya) e=a-b-d;T=ALL([a*a-b*b,a*a-d*d,a*a-e*e,a*b,a*d,a*e]>=0)- yang mungkin dapat di-golf lebih.
Ventero
2

MATLAB: 9!

Tidak banyak dari saya untuk menulis di sini

inpolygon

Dapat disebut seperti ini:

inpolygon(2/3, 2/3, [0 1 1], [0 0 1])

Output ditugaskan ke variabel bernama ans


Jika saya benar-benar harus menulis suatu fungsi, mungkin sesuatu seperti itu, mungkin dapat dioptimalkan:

function y=f(a,b,c,d)
inpolygon(a,b,c,d)
Dennis Jaheruddin
sumber
2
bisa lebih pendek menggunakan pegangan fungsi:f=@(a,b,c,d)inpolygon(a,b,c,d)
jpjacobs
2

C # 218 (149?)

using P=System.Drawing.PointF;
bool F(P[]p){for(int i=0;i<4;i++){p[i].X*=1e7f;p[i].Y*=1e7f;}P[]a=new P[3];Array.Copy(p,1,a,0,3);var g=new System.Drawing.Drawing2D.GraphicsPath();g.AddLines(a);return g.IsVisible(p[0]);}

Mungkin tidak seefisien karakter sebagai metode matematika, tapi itu menyenangkan menggunakan perpustakaan. Kebetulan juga agak lambat.

Juga memanfaatkan "Juga jangan khawatir tentang stabilitas numerik atau presisi floating-point." - Sayangnya, GraphicsPathmenggunakan ints secara internal, sehingga nilai dalam rentang -1 <f <1 hanya dapat memiliki tiga nilai yang mungkin. Karena float hanya memiliki 7 digit presisi, saya hanya mengalikan 1e7 untuk mengubahnya menjadi bilangan bulat. Hm, saya kira itu tidak benar-benar kehilangan presisi. Ini juga dapat dieksploitasi dengan cara lain: Saya mungkin bisa mengambil keuntungan dari mengabaikan presisi dan hanya memberikan jawaban yang "salah".

Jika saya boleh mengabaikan biaya karakter untuk mengimpor perpustakaan, 149 (paling tidak, System.Linqdan System.Drawingcukup standar pada sebagian besar proyek WinForms, tetapi System.Drawing.Drawing2Dmungkin sedikit sulit):

bool G(PointF[]p){for(int i=0;i<4;i++){p[i].X*=1e7f;p[i].Y*=1e7f;}var g=new GraphicsPath();g.AddLines(p.Skip(1).ToArray());return g.IsVisible(p[0]);}

Program uji (ya, jelek):

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using P=System.Drawing.PointF;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        Program prog = new Program();
        foreach (string test in
@"[(-0.31961, -0.12646), (0.38478, 0.37419), (-0.30613, -0.59754), (-0.85548, 0.6633)]
[(-0.87427, -0.00831), (0.78829, 0.60409), (-0.90904, -0.13856), (-0.80685, 0.48468)]
[(0.28997, -0.03668), (-0.28362, 0.42831), (0.39332, -0.07474), (-0.48694, -0.10497)]
[(-0.07783, 0.04415), (-0.34355, -0.07161), (0.59105, -0.93145), (0.29402, 0.90334)]
[(0.36107, 0.05389), (0.27103, 0.47754), (-0.00341, -0.79472), (0.82549, -0.29028)]
[(-0.01655, -0.20437), (-0.36194, -0.90281), (-0.26515, -0.4172), (0.36181, 0.51683)]
[(-0.12198, -0.45897), (-0.35128, -0.85405), (0.84566, 0.99364), (0.13767, 0.78618)]
[(-0.03847, -0.81531), (-0.18704, -0.33282), (-0.95717, -0.6337), (0.10976, -0.88374)]
[(0.07904, -0.06245), (0.95181, -0.84223), (-0.75583, -0.34406), (0.16785, 0.87519)]
[(-0.33485, 0.53875), (-0.25173, 0.51317), (-0.62441, -0.90698), (-0.47925, 0.74832)]
[(-0.99103, 0.43842), (0.78128, -0.10985), (-0.84714, -0.20558), (-0.08925, -0.78608)]
[(0.15087, -0.56212), (-0.87374, -0.3787), (0.86403, 0.60374), (0.01392, 0.84362)]
[(0.1114, 0.66496), (-0.92633, 0.27408), (0.92439, 0.43692), (0.8298, -0.29647)]
[(0.87786, -0.8594), (-0.42283, -0.97999), (0.58659, -0.327), (-0.22656, 0.80896)]
[(0.43525, -0.8923), (0.86119, 0.78278), (-0.01348, 0.98093), (-0.56244, -0.75129)]
[(-0.73365, 0.28332), (0.63263, 0.17177), (-0.38398, -0.43497), (-0.31123, 0.73168)]
[(-0.57694, -0.87713), (-0.93622, 0.89397), (0.93117, 0.40775), (0.2323, -0.30718)]
[(0.91059, 0.75966), (0.60118, 0.73186), (0.32178, 0.88296), (-0.90087, -0.26367)]
[(0.3463, -0.89397), (0.99108, 0.13557), (0.50122, -0.8724), (0.43385, 0.00167)]
[(0.88121, 0.36469), (-0.29829, 0.21429), (0.31395, 0.2734), (0.43267, -0.78192)]".Split('\n'))
        {
            string t = test.Replace("[(", "").Replace(")]", "");
            string[] points = t.Split(new string[] { "), (" }, StringSplitOptions.None);

            string[] p = points[0].Split(',');
            P[] xabc = new P[4];

            for (int i = 0; i < 4; i++)
            {
                p = points[i].Split(',');
                xabc[i] = new F(float.Parse(p[0]), float.Parse(p[1]));
            }

            Console.WriteLine(test + "=>" + prog.F(xabc));
        }

        Console.ReadKey();
    }

    bool G(PointF[]p)
    {
        for(int i=0;i<4;i++){p[i].X*=1e7f;p[i].Y*=1e7f;}
        var g=new GraphicsPath();
        g.AddLines(p.Skip(1).ToArray());
        return g.IsVisible(p[0]);
    }

    bool F(P[]p)
    {
        for(int i=0;i<4;i++){p[i].X*=1e7f;p[i].Y*=1e7f;}
        var g=new System.Drawing.Drawing2D.GraphicsPath();
        g.AddLines(p.Skip(1).ToArray());
        return g.IsVisible(p[0]);
    }
}
Bob
sumber
Lucu, mendapatkan mesin gambar untuk melakukan pekerjaan.
xnor
2

Haskell - 233 127

Menggunakan produk silang seperti dijelaskan di sini :

h(a,b)(p,q)(r,s)(t,u)=z a b p q r s==z a b r s t u&&z a b r s t u==z a b t u p q where z j k l m n o =(o-m)*(j-l)+(l-n)*(k-m)>0

Solusi sebelumnya diimplementasikan menggunakan koordinat barycentric dan formula yang dijelaskan dalam jawaban Stack Exchange ini :

g(p,q)(r,s)(t,u)(v,w)=
 let (j,k)=(p+(-r),q+(-s))
     (l,m)=(t+(-r),u+(-s))
     (n,o)=(v+(-r),w+(-s))
     d=l*o-n*m
     a=(j*(m-o)+k*(n-l)+l*o-n*m)/d
     b=(j*o-k*n)/d
     c=(k*l-j*m)/d
 in (0<=a&&a<1)&&(0<=b&&b<1)&&(0<=c&&c<1)

Keduanya berfungsi gdan hmengambil empat pasang, yang pertama adalah titik yang akan diuji untuk dimasukkan dan sisanya adalah koordinat dari simpul segitiga.

Untuk menguji dengan input sampel:

let trueTestCases =
  [((-0.31961, -0.12646), (0.38478, 0.37419), (-0.30613, -0.59754), (-0.85548, 0.6633)),
   ((-0.87427, -0.00831), (0.78829, 0.60409), (-0.90904, -0.13856), (-0.80685, 0.48468)),
   ((0.28997, -0.03668), (-0.28362, 0.42831), (0.39332, -0.07474), (-0.48694, -0.10497)),
   ((-0.07783, 0.04415), (-0.34355, -0.07161), (0.59105, -0.93145), (0.29402, 0.90334)),
   ((0.36107, 0.05389), (0.27103, 0.47754), (-0.00341, -0.79472), (0.82549, -0.29028)),
   ((-0.01655, -0.20437), (-0.36194, -0.90281), (-0.26515, -0.4172), (0.36181, 0.51683)),
   ((-0.12198, -0.45897), (-0.35128, -0.85405), (0.84566, 0.99364), (0.13767, 0.78618)),
   ((-0.03847, -0.81531), (-0.18704, -0.33282), (-0.95717, -0.6337), (0.10976, -0.88374)),
   ((0.07904, -0.06245), (0.95181, -0.84223), (-0.75583, -0.34406), (0.16785, 0.87519)),
   ((-0.33485, 0.53875), (-0.25173, 0.51317), (-0.62441, -0.90698), (-0.47925, 0.74832))]

let falseTestCases =
  [((-0.99103, 0.43842), (0.78128, -0.10985), (-0.84714, -0.20558), (-0.08925, -0.78608)),
   ((0.15087, -0.56212), (-0.87374, -0.3787), (0.86403, 0.60374), (0.01392, 0.84362)),
   ((0.1114, 0.66496), (-0.92633, 0.27408), (0.92439, 0.43692), (0.8298, -0.29647)),
   ((0.87786, -0.8594), (-0.42283, -0.97999), (0.58659, -0.327), (-0.22656, 0.80896)),
   ((0.43525, -0.8923), (0.86119, 0.78278), (-0.01348, 0.98093), (-0.56244, -0.75129)),
   ((-0.73365, 0.28332), (0.63263, 0.17177), (-0.38398, -0.43497), (-0.31123, 0.73168)),
   ((-0.57694, -0.87713), (-0.93622, 0.89397), (0.93117, 0.40775), (0.2323, -0.30718)),
   ((0.91059, 0.75966), (0.60118, 0.73186), (0.32178, 0.88296), (-0.90087, -0.26367)),
   ((0.3463, -0.89397), (0.99108, 0.13557), (0.50122, -0.8724), (0.43385, 0.00167)),
   ((0.88121, 0.36469), (-0.29829, 0.21429), (0.31395, 0.2734), (0.43267, -0.78192))]

type Point = (Double, Double)

test :: [(Point, Point, Point, Point)] -> [Bool]
test testCases =
  map (\((px,py),(ax,ay),(bx,by),(cx,cy)) -> h (px,py) (ax,ay) (bx,by) (cx,cy)) testCases

test trueTestCases --> [True,True,True,True,True,True,True,True,True,True]
test falseTestCases --> [False,False,False,False,False,False,False,False,False,False]

Solusi yang tidak digabungkan:

type Point = (Double, Double)

-- using cross products

triangulate' (a, b) (p, q) (r, s) (t, u) =
  (side a b p q r s == side a b r s t u) && (side a b r s t u == side a b t u p q)
  where side j k l m n o = (o - m) * (j - l) + (-n + l) * (k - m) >= 0

-- using barycentric coordinates

triangulate :: (Point, Point, Point, Point) -> Bool
triangulate ((px, py), (ax, ay), (bx, by), (cx, cy)) = 
  let (p'x, p'y) = (px + (-ax), py + (-ay))
      (b'x, b'y) = (bx + (-ax), by + (-ay))
      (c'x, c'y) = (cx + (-ax), cy + (-ay))
      d = b'x * c'y - c'x * b'y
      a = (p'x * (b'y - c'y) + p'y * (c'x - b'x) + b'x * c'y - c'x * b'y) / d
      b = (p'x * c'y - p'y * c'x) / d
      c = (p'y * b'x - p'x * b'y) / d
  in
      (0 <= a && a < 1) && (0 <= b && b < 1) && (0 <= c && c < 1)
OI
sumber
2

JavaScript (ES6) 120

C=(p,q,i,j,k,l,m,n,
 z=j*(m-k)+i*(l-n)+k*n-l*m,
 s=(j*m-i*n+(n-j)*p+(i-m)*q)/z,
 t=(i*l-j*k+(j-l)*p+(k-i)*q)/z
)=>s>0&t>0&s+t<1

Langsung disalin dari jawaban saya ke pertanyaan lain ini

Uji di konsol FireFox / FireBug

Keluarkan semua 1s

;[
C(-0.31961, -0.12646, 0.38478, 0.37419, -0.30613, -0.59754, -0.85548, 0.6633),
C(-0.87427, -0.00831, 0.78829, 0.60409, -0.90904, -0.13856, -0.80685, 0.48468),
C(0.28997, -0.03668, -0.28362, 0.42831, 0.39332, -0.07474, -0.48694, -0.10497),
C(-0.07783, 0.04415, -0.34355, -0.07161, 0.59105, -0.93145, 0.29402, 0.90334),
C(0.36107, 0.05389, 0.27103, 0.47754, -0.00341, -0.79472, 0.82549, -0.29028),
C(-0.01655, -0.20437, -0.36194, -0.90281, -0.26515, -0.4172, 0.36181, 0.51683),
C(-0.12198, -0.45897, -0.35128, -0.85405, 0.84566, 0.99364, 0.13767, 0.78618),
C(-0.03847, -0.81531, -0.18704, -0.33282, -0.95717, -0.6337, 0.10976, -0.88374),
C(0.07904, -0.06245, 0.95181, -0.84223, -0.75583, -0.34406, 0.16785, 0.87519),
C(-0.33485, 0.53875, -0.25173, 0.51317, -0.62441, -0.90698, -0.47925, 0.74832)
]

Keluarkan semua 0s

;[
C(-0.99103, 0.43842,0.78128, -0.10985,-0.84714, -0.20558,-0.08925, -0.78608),
C(0.15087, -0.56212,-0.87374, -0.3787,0.86403, 0.60374,0.01392, 0.84362),
C(0.1114, 0.66496,-0.92633, 0.27408,0.92439, 0.43692,0.8298, -0.29647),
C(0.87786, -0.8594,-0.42283, -0.97999,0.58659, -0.327,-0.22656, 0.80896),
C(0.43525, -0.8923,0.86119, 0.78278,-0.01348, 0.98093,-0.56244, -0.75129),
C(-0.73365, 0.28332,0.63263, 0.17177,-0.38398, -0.43497,-0.31123, 0.73168),
C(-0.57694, -0.87713,-0.93622, 0.89397,0.93117, 0.40775,0.2323, -0.30718),
C(0.91059, 0.75966,0.60118, 0.73186,0.32178, 0.88296,-0.90087, -0.26367),
C(0.3463, -0.89397,0.99108, 0.13557,0.50122, -0.8724,0.43385, 0.00167),
C(0.88121, 0.36469,-0.29829, 0.21429,0.31395, 0.2734,0.43267, -0.78192)
]
edc65
sumber
2

SmileBASIC, 111 100 karakter

DEF T X,Y,A,B,C,D,E,F
Q=9e5GCLS
GTRI(A-X)*Q,Q*(B-Y),Q*(C-X),Q*(D-Y),Q*(E-X),Q*(F-Y)?!!GSPOIT(0,0)END

Gambarlah segitiga dan periksa warna piksel pada titik tersebut. Segitiga ditingkatkan menjadi 99999x dan digeser sehingga titik untuk memeriksa akan berada pada (0,0) sebelum ditarik, untuk meminimalkan kehilangan presisi.

12Me21
sumber
2

Perakitan FPU Intel 8087, 222 220 byte

Hanya menggunakan perangkat keras FPU 8087 untuk menghitung. Berikut ini adalah versi yang belum dirakit (yang tidak diunggulkan dalam kasus ini) sebagai MACRO (akan memberi Anda 220 kode byte heksa):

; calculate the area of of a triangle ABC using determinate
; input: coordinates (float), Ax,Ay,Bx,By,Cx,Cy
; output: area in ST
TAREA   MACRO   A1,A2,B1,B2,C1,C2
    FLD  A1
    FLD  B2
    FLD  C2
    FSUB        ; ST = By - Cy
    FMUL        ; ST = Ax * ( By - Cy )
    FLD  B1 
    FLD  C2
    FLD  A2
    FSUB        ; ST = Cy - Ay
    FMUL        ; ST = Bx * ( Cy - Ay )
    FLD  C1
    FLD  A2
    FLD  B2
    FSUB        ; Ay - By
    FMUL        ; Cx * ( Ay - By )
    FADD        ; Cx * ( Ay - By ) + Bx * ( Cy - Ay )
    FADD        ; Cx * ( Ay - By ) + Bx * ( Cy - Ay ) + Ax * ( By - Cy )
    FLD1        ; make a value of 2
    FADD ST,ST  ; ST = 2
    FDIV        ; divide by 2
    FABS        ; take abs value
        ENDM

; determine if point X is in triangle ABC
; input: points X, A, B, C
; output: ZF=1 if X in triangle, ZF=0 if X not in triangle
TXINABC     MACRO X1,X2,A1,A2,B1,B2,C1,C2

    TAREA  A1,A2,B1,B2,C1,C2    ; ST(3) = area of triangle ABC
    TAREA  X1,X2,B1,B2,C1,C2    ; ST(2) = area of triangle XBC
    TAREA  A1,A2,X1,X2,C1,C2    ; ST(1) = area of triangle AXC
    TAREA  A1,A2,B1,B2,X1,X2    ; ST(0) = area of triangle ABX

    FADD        ; add areas of triangles with point
    FADD        ; ST = ST + ST(1) + ST(2)
    FCOMPP      ; compare ST to ST(1) and pop results
    FWAIT       ; sync CPU/FPU
    FSTSW R     ; store result flags to R
    MOV  AX, R  ; move result to AX
    SAHF        ; store result into CPU flags for conditional check
        ENDM

Penjelasan

Menggunakan determinasi untuk menghitung luas segitiga ABC, dan kemudian segitiga terbentuk dengan titik X dan dua titik lainnya dari segitiga ABC. Jika luas segitiga ABC sama dengan jumlah luas segitiga XBC + AXC + ABX, maka titik tersebut berada dalam segitiga. Hasilnya dikembalikan sebagai ZF.

Apa yang rapi tentang ini

Semua operasi matematika dan floating point dilakukan dalam perangkat keras dengan presisi diperpanjang 80-bit. Perbandingan floating point akhir juga dilakukan dalam perangkat keras sehingga akan sangat akurat.

Ini juga menggunakan delapan register tumpukan 8087 sekaligus.

Apa yang tidak begitu rapi tentang ini

Karena titik-titik segitiga harus dicolokkan kembali ke formula beberapa kali selama perhitungan, itu mengharuskan setiap variabel dalam memori dimuat ke register tumpukan FPU satu per satu dalam urutan yang benar. Meskipun ini dapat dengan mudah dimodelkan seperti fungsi sebagai MACRO, itu berarti bahwa kode diperluas setiap kali pada perakitan, membuat kode yang berlebihan. 41 byte disimpan dengan memindahkan beberapa segmen kode berulang yang sama ke dalam PROCs. Namun itu membuat kode kurang dapat dibaca, sehingga daftar di atas adalah tanpanya (itulah sebabnya itu diberi label "ungolfed").

Tes

Berikut ini adalah program pengujian menggunakan IBM DOS yang menampilkan keluaran:

TTEST   MACRO T
        LOCAL IS_IN_TRI

    TXINABC T,T+4*1,T+4*2,T+4*3,T+4*4,T+4*5,T+4*6,T+4*7
    MOV  DX, OFFSET TEQ     ; load true string by default 
    JZ   IS_IN_TRI          ; if ZF=1, it is in triangle, skip to display
    MOV  DX, OFFSET FEQ     ; otherwise ZF=0 means not in triangle, so load false string
IS_IN_TRI:
    MOV  AH, 9              ; DOS write string function
    INT  21H 
        ENDM

START:
    FINIT                   ; reset 8087

    TTEST   T0              ; true tests
    TTEST   T1
    TTEST   T2
    TTEST   T3
    TTEST   T4
    TTEST   T5
    TTEST   T6
    TTEST   T7
    TTEST   T8
    TTEST   T9

    TTEST   F0              ; false tests
    TTEST   F1
    TTEST   F2
    TTEST   F3
    TTEST   F4
    TTEST   F5
    TTEST   F6  
    TTEST   F7
    TTEST   F8  
    TTEST   F9

    RET         ; return to DOS

T0  DD  -0.31961, -0.12646, 0.38478, 0.37419, -0.30613, -0.59754, -0.85548, 0.6633
T1  DD  -0.87427, -0.00831, 0.78829, 0.60409, -0.90904, -0.13856, -0.80685, 0.48468
T2  DD  0.28997, -0.03668, -0.28362, 0.42831, 0.39332, -0.07474, -0.48694, -0.10497
T3  DD  -0.07783, 0.04415, -0.34355, -0.07161, 0.59105, -0.93145, 0.29402, 0.90334
T4  DD  0.36107, 0.05389, 0.27103, 0.47754, -0.00341, -0.79472, 0.82549, -0.29028
T5  DD  -0.01655, -0.20437, -0.36194, -0.90281, -0.26515, -0.4172, 0.36181, 0.51683
T6  DD  -0.12198, -0.45897, -0.35128, -0.85405, 0.84566, 0.99364, 0.13767, 0.78618
T7  DD  -0.03847, -0.81531, -0.18704, -0.33282, -0.95717, -0.6337, 0.10976, -0.88374
T8  DD  0.07904, -0.06245, 0.95181, -0.84223, -0.75583, -0.34406, 0.16785, 0.87519
T9  DD  -0.33485, 0.53875, -0.25173, 0.51317, -0.62441, -0.90698, -0.47925, 0.74832

F0  DD  -0.99103, 0.43842, 0.78128, -0.10985, -0.84714, -0.20558, -0.08925, -0.78608
F1  DD  0.15087, -0.56212, -0.87374, -0.3787, 0.86403, 0.60374, 0.01392, 0.84362
F2  DD  0.1114, 0.66496, -0.92633, 0.27408, 0.92439, 0.43692, 0.8298, -0.29647
F3  DD  0.87786, -0.8594, -0.42283, -0.97999, 0.58659, -0.327, -0.22656, 0.80896
F4  DD  0.43525, -0.8923, 0.86119, 0.78278, -0.01348, 0.98093, -0.56244, -0.75129
F5  DD  -0.73365, 0.28332, 0.63263, 0.17177, -0.38398, -0.43497, -0.31123, 0.73168
F6  DD  -0.57694, -0.87713, -0.93622, 0.89397, 0.93117, 0.40775, 0.2323, -0.30718
F7  DD  0.91059, 0.75966, 0.60118, 0.73186, 0.32178, 0.88296, -0.90087, -0.26367
F8  DD  0.3463, -0.89397, 0.99108, 0.13557, 0.50122, -0.8724, 0.43385, 0.00167
F9  DD  0.88121, 0.36469, -0.29829, 0.21429, 0.31395, 0.2734, 0.43267, -0.78192

TEQ DB 'In Triangle',0DH,0AH,'$'
FEQ DB 'Not In Triangle',0DH,0AH,'$'

Keluaran

In Triangle
In Triangle
In Triangle
In Triangle
In Triangle
In Triangle
In Triangle
In Triangle
In Triangle
In Triangle
Not In Triangle
Not In Triangle
Not In Triangle
Not In Triangle
Not In Triangle
Not In Triangle
Not In Triangle
Not In Triangle
Not In Triangle
Not In Triangle
640KB
sumber
1

C 414 (dulu 465)

Golf

#define D double 
int F(D ax,D ay,D bx,D by,D cx,D cy,D px,D py){int y=0;double J,K;D m=(ax-bx<0.001)?(by-ay)/(ax-bx):1000;D b=m*ax+ay;J=m*cx-cy+b;K=m*px-py+b;if(J*K>=0)y=1;return y;}D T[8],k;int i,n;void G(){while(i<8){scanf("%lf",&k);T[i++]=k;}n+=F(T[2],T[3],T[4],T[5],T[6],T[7],T[0],T[1]);n+=F(T[4],T[5],T[6],T[7],T[2],T[3],T[0],T[1]);n+=F(T[2],T[3],T[6],T[7],T[4],T[5],T[0],T[1]);printf(n==3?"True":"False");}

Deklarasi fungsi asli ditambahkan untuk penjelasan

/**
* determine if points C & P are on same side of line AB
* return 1 if true, 0 otherwise
*/
int PointsSameSide(D ax,D ay,D bx,D by,D cx, D cy, D px, D py);

Ditulis ulang sebagai fungsi bernama: input melalui stdin satu baris atau semua dalam satu baris yang dipisahkan ruang.

#define D double
int F(D ax,D ay,D bx,D by,D cx, D cy, D px, D py)
{
int y=0;
double J,K;
D m = (ax-bx<0.001)?(by-ay)/(ax-bx):1000;
D b = m*ax+ay;
J=m*cx-cy+b;
K=m*px-py+b;
if(J*K>=0)y=1;
return y;
}
double T[8],k;
int i,n;
void G()
{
while(i<8){scanf("%lf",&k);T[i++]=k;}
n+=F(T[2],T[3],T[4],T[5],T[6],T[7],T[0],T[1]);
n+=F(T[4],T[5],T[6],T[7],T[2],T[3],T[0],T[1]);
n+=F(T[2],T[3],T[6],T[7],T[4],T[5],T[0],T[1]);
printf(n==3?"True":"False");
}
bacchusbeale
sumber
3
Anda dapat menghemat beberapa byte dengan menyingkirkan baris baru dan ruang yang tidak perlu. Selain itu, Anda telah doublemendefinisikan ulang Dtetapi Anda masih menggunakan doubledalam kode.
gronostaj
1

Jawa, 149 karakter

g=Math.atan2(100*(d-y),(a-x));h=Math.atan2(100*(e-y),(b-x));i=Math.atan2(100*(f-y),(c-x));k=Math.round(Math.abs(g-h)+Math.abs(h-i)+Math.abs(i-g))==6;

Mengerikan mengingat saya harus menulis "Matematika." setiap saat. Ini adalah program aktual:

package mathPackage;
public class InTriangle {
public static void main(String[] args) {
    boolean k;
    double a=-1,b=0,c=1,d=0,e=1,f=0,x=0,y=0.4;
    double g,h,i;
    g=Math.atan2(100*(d-y),(a-x));
    h=Math.atan2(100*(e-y),(b-x));
    i=Math.atan2(100*(f-y),(c-x));
    k=Math.round(Math.abs(g-h)+Math.abs(h-i)+Math.abs(i-g))==6;
    System.out.println(k);
    System.out.println(g);
    System.out.println(h);
    System.out.println(i);
    System.out.print(Math.abs(g-h)+Math.abs(h-i)+Math.abs(i-g));
}
}

di mana a adalah x dari titik a, b adalah x dari titik b, c untuk x dari c, d adalah y dari a, e adalah y dari b, f adalah y dari c, dan x dan y adalah x dan y pokoknya. Boolean k menentukan apakah itu benar atau tidak.

colorado777
sumber
1
Untuk apa 100*?
xnor
1

JavaScript 125/198

Jika poin disediakan dalam 8 argumen:

function d(x,y,a,b,c,d,e,f){function z(a,b,c,d){return(y-b)*(c-a)-(x-a)*(d-b)>0}return(z(a,b,c,d)+z(c,d,e,f)+z(e,f,a,b))%3<1}

Jika poin disediakan dalam array 2 dimensi:

function c(s){return (z(s[1][0],s[1][1],s[2][0],s[2][1])+z(s[2][0],s[2][1],s[3][0],s[3][1])+z(s[3][0],s[3][1],s[1][0],s[1][1]))%3<1;function z(a,b,c,d){return (s[0][1]-b)*(c-a)-(s[0][0]-a)*(d-b)>0}}

Kode ini tidak menggunakan matematika vektor mewah mana pun. Sebagai gantinya, itu hanya menggunakan trik aljabar sederhana untuk menentukan apakah titik itu di dalam segitiga atau tidak. Rumus:

(y-b)(c-a) - (x-a)(d-b)

yang memberitahu titik adalah di sisi mana dari sebuah garis , berasal dari menyusun ulang definisi kemiringan:

            m = (y2-y1)/(x2-x1)
      (y2-y1) = m(x2-x1)
       (y-y1) = m(x-x1)     ,substituting point we are testing (x,y) to be the 2nd point
       (y-y1) = (x-x1)(y2-y1)/(x2-x1)  ,substitute back the original definition of m
(y-y1)(x2-x1) = (x-x1)(y2-y1)    <-- left side will be greater than the right side, if
                                     the point is on the left; otherwise, it's on the right
            0 = (y-b)(c-a)-(x-a)(d-b) ,where (a,b)=(x1,y1), (c,d)=(x2,y2)

Jika kita menguji semua 3 sisi, ketiga harus menghasilkan beberapa angka dengan tanda yang sama hanya ketika titik berada di dalam segitiga karena kita mengujinya di sekitar segitiga. Jika titik berada di samping maka salah satu tes harus mengembalikan 0.

kode uji jsFiddle: http://jsfiddle.net/DerekL/zEzZU/

var l = [[-0.31961, -0.12646, 0.38478, 0.37419, -0.30613, -0.59754, -0.85548, 0.6633],[-0.87427, -0.00831, 0.78829, 0.60409, -0.90904, -0.13856, -0.80685, 0.48468],[0.28997, -0.03668, -0.28362, 0.42831, 0.39332, -0.07474, -0.48694, -0.10497],[-0.07783, 0.04415, -0.34355, -0.07161, 0.59105, -0.93145, 0.29402, 0.90334],[0.36107, 0.05389, 0.27103, 0.47754, -0.00341, -0.79472, 0.82549, -0.29028],[-0.01655, -0.20437, -0.36194, -0.90281, -0.26515, -0.4172, 0.36181, 0.51683],[-0.12198, -0.45897, -0.35128, -0.85405, 0.84566, 0.99364, 0.13767, 0.78618],[-0.03847, -0.81531, -0.18704, -0.33282, -0.95717, -0.6337, 0.10976, -0.88374],[0.07904, -0.06245, 0.95181, -0.84223, -0.75583, -0.34406, 0.16785, 0.87519],[-0.33485, 0.53875, -0.25173, 0.51317, -0.62441, -0.90698, -0.47925, 0.74832],
         [-0.99103, 0.43842, 0.78128, -0.10985, -0.84714, -0.20558, -0.08925, -0.78608],[0.15087, -0.56212, -0.87374, -0.3787, 0.86403, 0.60374, 0.01392, 0.84362],[0.1114, 0.66496, -0.92633, 0.27408, 0.92439, 0.43692, 0.8298, -0.29647],[0.87786, -0.8594, -0.42283, -0.97999, 0.58659, -0.327, -0.22656, 0.80896],[0.43525, -0.8923, 0.86119, 0.78278, -0.01348, 0.98093, -0.56244, -0.75129],[-0.73365, 0.28332, 0.63263, 0.17177, -0.38398, -0.43497, -0.31123, 0.73168],[-0.57694, -0.87713, -0.93622, 0.89397, 0.93117, 0.40775, 0.2323, -0.30718],[0.91059, 0.75966, 0.60118, 0.73186, 0.32178, 0.88296, -0.90087, -0.26367],[0.3463, -0.89397, 0.99108, 0.13557, 0.50122, -0.8724, 0.43385, 0.00167],[0.88121, 0.36469, -0.29829, 0.21429, 0.31395, 0.2734, 0.43267, -0.78192]];

function d(x,y,a,b,c,d,e,f){function z(a,b,c,d){return(y-b)*(c-a)-(x-a)*(d-b)>0}return(z(a,b,c,d)+z(c,d,e,f)+z(e,f,a,b))%3<1}

for(var i = 0; i < l.length; i++){
    console.log(d.apply(undefined,l[i]));    //10 true, 10 false
}

97 karakter (tidak termasuk spasi atau tab) dihitung jika dikonversi ke CoffeeScript:

d=(x,y,a,b,c,d,e,f)->
    z=(a,b,c,d)->
        (y-b)*(c-a)-(x-a)*(d-b)>0
    (z(a,b,c,d)+z(c,d,e,f)+z(e,f,a,b))%3<1

115 karakter jika diubah menjadi ES6:

d=(x,y,a,b,c,d,e,f)=>{z=(a,b,c,d)=>{return (y-b)*(c-a)-(x-a)*(d-b)>0};return(z(a,b,c,d)+z(c,d,e,f)+z(e,f,a,b))%3<1}
Derek 朕 會 功夫
sumber
Itu adalah "matematika vektor mewah" yang saya gunakan: D (bukan pendekatan koordinat barycentric mewah yang dilakukan beberapa orang lain). Seperti jawaban pilihan teratas, Anda dapat menyimpan beberapa byte dengan menggunakan ES6 dan mendefinisikan fungsi seperti d=(x,y,...)=>{...}. Dalam kasus Anda, Anda dapat menyimpan lebih banyak lagi dengan menggunakan CoffeeScript, yang tidak perlu return: pastebin.com/RVFk1D5k ... dan dalam hal apa pun Anda dapat menyimpan satu byte dengan menggunakan <1alih-alih ==0.
Martin Ender
@ m.buettner: O Saya pikir persamaan yang saya gunakan tidak ada hubungannya dengan vektor (berasal dari aljabar sederhana) tetapi ternyata keduanya menghasilkan persamaan yang sama. Matematika itu luar biasa.
Derek 朕 會 功夫
1

R, 23

Terinspirasi oleh MATLAB ,

SDMTools::pnt.in.poly()

disebut seperti di SDMTools::pnt.in.poly(point,triangle)mana pointvektor panjang-2 dan trianglematriks 3x2 dari simpul. SDMTools tersedia di CRAN.

shadowtalker
sumber
1

Mathematica, 38 karakter

RegionMember[Polygon[#[[1]]],#[[2]]] &

Contoh:

d = {{{0, 0}, {1, 0}, {.5, .7}}, {.5, .6}};

RegionMember[Polygon[#[[1]]], #[[2]]] & @ d

(* Benar *)

David G. Stork
sumber
Merupakan standar untuk menghitung spasi sebagai karakter, tetapi mungkin di sini Anda dapat menghapusnya tanpa merusaknya.
xnor
1
Selain itu, Anda perlu mengambil input dan menghasilkan output daripada menggunakan variabel yang telah ditentukan. Anda dapat mencari beberapa jawaban Mathematica untuk melihat bagaimana mereka melakukannya.
xnor
0

C (gcc) , 108 byte

i;f(a,b,c,d,e,f,g,h)float a,b,c,d,e,f,g,h;{i=(e-=a)*(h-=b)>(f-=b)*(g-=a);i=(c-=a)*f>(d-=b)*e==i&i==g*d>h*c;}

Cobalah online!

Membawa tiga produk silang dan kembali 1jika tanda komponen tidak berubah.

plafon
sumber