ตรวจสอบว่าจุดอยู่ภายในรูปสามเหลี่ยมหรือไม่


40

เป้าหมายของคุณคือการพิจารณาว่าจุด 2D ที่ได้รับอยู่ในพื้นที่ของสามเหลี่ยมที่มีจุดยอด A, B, C หรือไม่

เขียนฟังก์ชั่นที่ใช้ในพิกัดของจุดทดสอบ X และจุดยอดสามเหลี่ยมสามรูป (นั่นคือทั้งหมด 8 พิกัด) และส่งกลับค่าจริงถ้าจุดนั้นอยู่ภายในสามเหลี่ยมนั้นและเท็จถ้าอยู่นอก

ไม่ต้องกังวลเกี่ยวกับกรณีขอบ หากจุดนั้นอยู่บนขอบเขตของสามเหลี่ยม (ขอบหรือจุดสุดยอด) หรือสามเหลี่ยมนั้นเป็นส่วนของเส้นตรงโค้ดของคุณสามารถทำอะไรก็ได้รวมถึงการกระแทก ยังไม่ต้องกังวลกับความเสถียรเชิงตัวเลขหรือความแม่นยำจุดลอยตัว

รหัสของคุณจะต้องเป็นชื่อฟังก์ชั่น จะไม่ยอมรับข้อมูลโค้ด

ตัวละครที่ชนะน้อยที่สุด

การป้อนข้อมูล:

แปดตัวเลขจริงที่แสดงถึงพิกัด (-1,1)ตัวเลขจะอยู่ในช่วง

รูปแบบการป้อนข้อมูลที่แน่นอนมีความยืดหยุ่น ยกตัวอย่างเช่นคุณสามารถใช้ตัวเลขแปดตัวรายการแปดหลักรายการสี่จุดแต่ละจุดที่กำหนดโดย tuple เมทริกซ์ 2 * 4 จำนวนเชิงซ้อนสี่จำนวนสองรายการของพิกัด x และพิกัด y และอื่น ๆ

อินพุตต้องเป็นตัวเลขในคอนเทนเนอร์บางตัวโดยไม่มีข้อมูลเพิ่มเติม คุณไม่สามารถใช้อินพุตเพื่อดำเนินการประมวลผลล่วงหน้าและคุณไม่จำเป็นต้องมีข้อ จำกัด ใด ๆ ในอินพุตเช่นต้องการให้มีการให้คะแนนในพิกัด y จากน้อยไปหามาก ข้อมูลที่คุณป้อนจะต้องอนุญาตให้ใช้พิกัดแปดพิกัดใด ๆ (แม้ว่ารหัสของคุณจะทำงานโดยพลการในกรณีขอบที่ระบุไว้ก่อนหน้านี้)

โปรดระบุรูปแบบการป้อนข้อมูลของคุณ

เอาท์พุท:

ไม่ว่าจะเป็นบูลีนTrue/ Falseหมายเลขที่สอดคล้องกัน1/ 0หรือแอนะล็อกในภาษาของคุณ

กรณีทดสอบ

อินพุตจะได้รับรายการ[X,A,B,C]ของสิ่งอันดับสี่จุดทดสอบก่อนจากนั้นจุดยอดสามเหลี่ยมทั้งสาม ผมได้จัดกลุ่มพวกเขาเป็นผู้ที่มีผลควรจะเป็นและผู้ที่ควรจะเป็นTrueFalse

True ตัวอย่าง:

[(-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.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)]

คำจำกัดความของตัวละครของคุณคืออะไร? ascii? เข้ารหัสใน 7 บิต ในไบต์? Unicode ใด ๆ
isaacg

คุณแนะนำอะไร? มีวิธีแก้ไขปัญหาที่ใช้รหัสบีบอัดอยู่แล้ว
xnor

โดยทั่วไปแล้วฉันเชื่อว่าไบต์ใช้สำหรับอักขระที่ไม่ใช่ ASCII เพราะมิฉะนั้นประโยชน์ Utf-32 นั้นไม่สามารถเอาชนะได้
isaacg

ฉันกลับไปไม่ได้แล้ว อักขระ Unicode ใด ๆ คืออักขระ บีบอัดถ้าคุณต้องการ
xnor

คำตอบ:


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}

รุ่น ECMAScript 6 (ขอบคุณ m.buettner บันทึกได้ 6 ตัว)

$=(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}

เรียกว่าเป็นเช่นนี้ (ส่งคืนtrueหรือfalse):

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

ใช้คณิตศาสตร์พิกัด barycentricแฟนซีโดยอ้างอิงจากคำตอบนี้ เวอร์ชันที่ไม่ดีนักเพื่อความเพลิดเพลินในการอ่านของคุณมีดังนี้:

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;
}

12
+1 หากชื่อพารามิเตอร์เท่านั้น!
Matt

ทำไมคุณต้องทำลาย UserScript นับตัวละครของฉัน ???
kitcar2000

@ kitcar2000 คุณหมายถึงอะไร
อับราฮัม

กฎบอกว่ามีการนับตัวอักษรไม่ใช่ไบต์ ดังนั้นคุณสามารถใช้สิ่งนี้: xem.github.io/obfuscatweetเพื่อให้พอดีกับ 122 ตัวอักษร
xem

1
ฉันเข้าใจผิดหรือคุณอาจจะได้ใช้(a*(l-n)+i*(g-e)+n*e-g*l)แทน(-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

ความพยายามในการเล่นรหัสกอล์ฟครั้งแรกของฉัน!

รหัส

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

ใช้เป็นอินพุต (x, y, t) โดยที่ (x, y) คือจุดที่เราตรวจสอบและ t คือรูปสามเหลี่ยม t = (x1, y1), (x2, y2), (x3, y3)

คำอธิบาย

ฉันกำลังคำนวณดีเทอร์มิแนนต์ของเมทริกซ์

| 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  |

ปัจจัยเหล่านี้เป็นตัวแทนของระยะทางที่ลงนามจากด้านข้างของรูปสามเหลี่ยมไปยังจุด (x, y) หากพวกเขาทั้งหมดมีเครื่องหมายเหมือนกันดังนั้นจุดนั้นจะอยู่ในด้านเดียวกันของทุกบรรทัดและมีอยู่ในรูปสามเหลี่ยม

ในโค้ดด้านบนa*y+c*b+d*x-d*a-c*y-b*xเป็นตัวกำหนดหนึ่งในเมทริกซ์เหล่านี้

ฉันใช้ความจริงที่True+True+True==3และFalse+False+False==0เพื่อตรวจสอบว่าปัจจัยเหล่านี้ทั้งหมดมีสัญญาณเดียวกัน

ฉันจะทำให้การใช้งานของ ธ ดัชนีรายการเชิงลบโดยใช้แทนt[-1]t[(i+1)%3]

ขอบคุณ Peter สำหรับแนวคิดที่จะใช้s%3<1แทนs in(0,3)การตรวจสอบว่า s เป็น 0 หรือ 3!

เวอร์ชันของ Sagemath

ไม่ใช่โซลูชันที่แตกต่างดังนั้นฉันจึงรวมไว้ในคำตอบนี้โซลูชัน sagemath ที่ใช้80ตัวอักษร:

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

ที่ไหนp=[x,y]และt=[[x1,y1],[x2,y2],[x3,y3]]


1
อาจs in (0,3)ย่อให้สั้นลงไปs%3<1?
Peter Taylor

1
การใช้ดัชนีเชิงลบสามารถ tweaked เพื่อบันทึกอีกหนึ่ง: -1,0,1 ... t[i]+t[i+1]เทียบเท่ากับ0,1,2 ... t[i-1]+t[i]
Peter Taylor

@PeterTaylor ถูกต้องอย่างแน่นอน! น่าเสียดายที่ฉันลบพื้นที่ในin -1,0,1ก่อนที่จะอ่านนี้ ที่จริงแล้ววิธีการของคุณอ่านง่ายขึ้นฉันจะใช้มันต่อไป
Alex L

1
ยินดีต้อนรับสู่โค้ดกอล์ฟ! คุณสามารถกำจัดวงเล็บเหลี่ยมสำหรับความเข้าใจในรายการภายในsumถ้าคุณใส่0,1,2วงเล็บในวงเล็บซึ่งเป็นตัวละครโดยแทนที่ช่องว่าง เหตุผลก็คือ Python อนุญาตให้ส่งผ่านความเข้าใจที่ไม่ได้แยกไปยังฟังก์ชัน แต่เครื่องหมายจุลภาคใน tuple เปล่า1,2,3ทำให้เกิดความสับสนเพราะพยายามแยกวิเคราะห์เป็นอาร์กิวเมนต์แยกต่างหาก
xnor

16

Mathematica, 67 ไบต์

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

ฟังก์ชั่นใช้เวลาสองข้อโต้แย้งจุดXและรายการของจุด{A,B,C}ซึ่งจะเรียกว่า#และ#2ตามลำดับ นั่นคือถ้าคุณโทร

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

แล้วคุณจะได้รับ#เป็นXและเป็น#2 {A,B,C}(โปรดทราบว่ามีอีกสองฟังก์ชั่นที่ไม่ระบุชื่อซ้อนอยู่ภายในรหัส - #และ#2มีความหมายที่แตกต่างกันภายในนั้น)

นี่คือคำอธิบายของฟังก์ชันเอง:

                                              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. *)

โปรดทราบว่าฟังก์ชั่นนี้จะใช้งานได้จริงกับนูนใด ๆ n-gon ตราบใดที่จุดยอดของมันจะได้รับตามลำดับตามเข็มนาฬิกาหรือทวนเข็มนาฬิกา


จะมีประสิทธิภาพมากกว่าหรือไม่หากตรวจสอบว่าผลิตภัณฑ์ของระยะทางเป็นบวกมากกว่าถ้าสัญญาณทั้งหมดเท่ากันหรือไม่ ฉันไม่ Mathematica แต่ดูเหมือนว่าควรจะง่ายกว่า
isaacg

@isaacg มีสามเงื่อนไขดังนั้นหากพวกเขาเป็นลบทั้งหมดผลิตภัณฑ์ของพวกเขาเป็นลบและหากพวกเขาทั้งหมดเป็นบวกผลิตภัณฑ์ของพวกเขาเป็นบวก วิธีการของคุณจะใช้งานได้ก็ต่อเมื่อเครื่องหมายของตัวเลขสองตัวนั้นเท่ากัน
Martin Ender

ทำไมไม่ใช้Det?
alephalpha

@alephalpha ส่วนใหญ่เป็นเพราะฉันไม่ได้คิดถึงมัน : P ... ฉันจะตรวจสอบสิ่งนั้น
Martin Ender

@alephalpha อืมฉันไม่สามารถหาวิธีที่จะสร้างเมทริกซ์ที่จำเป็นสามตัวในตัวละครน้อย
Martin Ender

7

CJam, 66 63 59 52 46 34 32 31 30 28 ตัวอักษร

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

หลังจากแปลงสตริง Unicode แล้วโค้ดต่อไปนี้ ( 33 ไบต์ ) จะได้รับการประเมิน:

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

คาดว่าX [A B C]เป็น input [double double]ซึ่งแต่ละจุดจะอยู่ในรูป เอาต์พุตคือ 1 หรือ 0

ลองออนไลน์

ขอบคุณมากที่คุณได้ไปที่ผู้ใช้23013สำหรับการบันทึก 6 ตัวอักษร (13 ไบต์ของรหัสที่ไม่มีการบีบอัด)!

กรณีทดสอบ

$ 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]

นั่นคือฟังก์ชั่นที่ตั้งชื่อหรือไม่?
Martin Ender

@ m.buettner: เรียงจาก วิกิพีเดียอย่างเป็นทางการกล่าวว่าต่อไปนี้: บล็อก - ส่วนโปรแกรมที่คั่นด้วย{และ}และถือว่าเป็นหน่วยเดียว คล้ายกับรหัสบล็อกใน C / java ยกเว้นบล็อกเป็นวัตถุชั้นหนึ่งและสามารถกำหนดให้กับตัวแปร (เช่นการกำหนดฟังก์ชั่น)
Dennis

1
@xnor 1m<@m*เตรียม X 3 คู่และi+1จุดยอด( th) ถัดไปของรูปสามเหลี่ยม @-@@-ย้ายiจุดยอดปัจจุบัน ( th) ไปที่จุดเริ่มต้น (และทำมิรเรอร์ถ้ามันไม่ใช่@-\@-แต่มันไม่สำคัญ) @@*@@*>คำนวณแกน z ของผลิตภัณฑ์กากบาทหรือดีเทอร์มิแนนต์และส่งคืน1ถ้ามันเป็นลบ :+3%!ส่งกลับไม่ว่าพวกเขาจะเหมือนกันทั้งหมดนั่นคือทั้ง 3 เป็นลบหรือไม่ลบซึ่งหมายถึงบวกยกเว้นสำหรับกรณีขอบ ฉันคิดว่าการอ่าน CJam นั้นยากกว่าการตีกอล์ฟ
jimmy23013

1
37 {[_1m<\]z\f{f{+~@-@@-}~@@*@@*>})-!}:Tไบต์: ใช้2m>หรือWm<เพื่อความปลอดภัย Unicode
jimmy23013

1
33 ไบต์:{2*2/\f{f{+~@-@@-}~@@*@@*>})-!}:T
jimmy23013

5

C - 156 ไบต์

อินพุตคืออาร์เรย์ 3 ลอยใน X, 3 ลอยใน Y และแยก x และ y สำหรับจุดทดสอบ โบนัส: จัดการกรณีขอบทั้งหมด!

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;}

ดัดแปลงมาจาก PNPOLY


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 - ทดสอบในจาวาสคริปต์
bebe

@bebe - ทำให้เกิดข้อผิดพลาดทางไวยากรณ์
Derek 朕會功夫

ที่ไม่ก่อให้เกิดข้อผิดพลาดทางไวยากรณ์
bebe

4

Pyth 1.0.5 , 57 54 51

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

นิยามฟังก์ชัน g ซึ่งรับสองอินพุต: จุดทดสอบจากนั้นรายการของจุดยอดของรูปสามเหลี่ยม ขาออกและTrue Falseหมายเหตุ: ทำลายอินพุตโดยเฉพาะ b รายการของจุดยอดของรูปสามเหลี่ยม

ลองมันนี่ ตัวอักษรสองสามตัวสุดท้ายgvwvwเรียกใช้ฟังก์ชันด้วยเคสทดสอบในสองบรรทัดถัดไป

ขึ้นอยู่กับอัลกอริทึมนี้

คำอธิบาย:

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)

สงคราม CJam - Pyth โหมกระหน่ำ!


นี่ควรเป็นชื่อฟังก์ชั่น คือwการป้อนข้อมูล STDIN?
xnor

@ xnor โอ๊ะฉันพลาดคำอธิบายนั้น จะแก้ไข
isaacg

@xnor ฟังก์ชั่นที่พิมพ์คำตอบได้รับอนุญาตหรือไม่หรือพวกเขาจะต้องส่งคืนคำตอบหรือไม่? ปัจจุบันนี้พิมพ์คำตอบออกมา แต่ฉันสามารถคืนมันให้กับตัวละครอีกหนึ่งตัวได้
isaacg

ส่งคืนคำตอบ
xnor

คุณอาจจะสามารถบันทึกตัวอักษรโดยการเปลี่ยนเคาน์เตอร์Zพร้อมกับชุดที่ว่างเปล่าที่คุณสะสมด้วยZ|=แล้วทดสอบความยาวของมันเพื่อดูว่าเพียง0's หรือ1ได้เห็น? กลยุทธ์ดังกล่าวใช้เวลานานขึ้นใน Python แต่อาจจะคุ้มค่ากับการใช้ Pythis แบบดั้งเดิม
xnor

4

J 64 45 (42 โดยไม่มีการมอบหมาย)

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

การมอบหมายไม่จำเป็นสำหรับสิ่งที่จะเป็นฟังก์ชั่นดังนั้นไม่แน่ใจว่าจะนับหรือไม่ การใช้ประโยชน์จากอินพุตที่ยืดหยุ่น: ฉันต้องการอาร์เรย์ (1 + จำนวนจุดยอด) x (มิติของพื้นที่)

หวังว่าจะได้คะแนนพิเศษบางอย่างที่นี่ ... : สิ่งนี้ใช้ได้กับทุกมิติของ simplex ไม่เพียงแค่สามเหลี่ยมในเครื่องบิน แต่ยังมีพีระมิด 3 ด้านในพื้นที่ 3 มิติและอื่น ๆ นอกจากนี้ยังใช้งานได้เมื่อจำนวนจุดยอดของเริมมีขนาดเล็กกว่า (n + 1) จากนั้นจะคำนวณว่าการฉายของจุดลงบนเริมอยู่ภายในหรือไม่

มันจะแปลงเป็นพิกัด barycentricจากนั้นตรวจสอบค่าลบเพื่อระบุว่าจุดนั้นอยู่นอก สนใจที่ J ใช้ _ เพื่อลบ

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

ทำงานกับตัวอย่างที่กำหนด:

   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

ฉันขอฟังก์ชั่นที่มีชื่อดังนั้นตัวละครที่ได้รับมอบหมายจึงถูกนับ นี่คือบางจุดสำหรับการสรุปทั่วไปของรูปหลายเหลี่ยม! ······
xnor

ที่จริงแล้วฉันไม่ได้พูดคุยกับรูปหลายเหลี่ยมได้ค่อนข้างธรรมดา แต่รู้จักกับ N-dimension simplexes ที่มีN+1จุดยอดสูงสุด ยกตัวอย่างเช่นพีระมิด 4 จุดยอดในพื้นที่ 3 มิติหรือ 5 จุดยอดในพื้นที่ 4 มิติ จำนวนจุดยอดสามารถต่ำกว่าได้N+1ซึ่งในกรณีนี้อัลกอริธึมดูว่าการฉายฉากมุมฉากบนไฮเปอร์เพลนที่ซิมเพล็กซ์อาศัยอยู่ในเริมอยู่หรือไม่ (เช่น 2 จุดซิมเพล็กซ์ใน 2-D ไม่ว่าการฉายภาพนี้จะอยู่ระหว่างจุดสิ้นสุด)
jpjacobs

4

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

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]}

หรือ 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]}

หรือ ES6 unicode-obfuscated (114 ตัวอักษร):

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

ตัวอย่าง: http://jsfiddle.net/xH8mV/

การทำให้งง Unicode ที่ทำกับ: http://xem.github.io/obfuscatweet/


ดูเหมือนจะไม่ได้ผลลัพธ์ที่ถูกต้องเมื่อจุดอยู่ใกล้กับด้านข้าง: jsfiddle.net/L2B2Aฉันเชื่อว่านี่เป็นเพราะอินพุตทั้งหมดอยู่ระหว่าง (-1,1) และรหัสของคุณทดสอบแค่ 4 พิกเซลเท่านั้น ต้นกำเนิด
Derek 朕會功夫

ถูกต้องเพื่อให้พอดีกับตัวอย่างฉันควรเปลี่ยนต้นกำเนิดและขนาดของผืนผ้าใบของฉันเพื่อจัดการรูปสามเหลี่ยมภายใน [-1,1] แต่ทำไมสามเหลี่ยมเหล่านี้ถึงมีขนาดเล็กมาก?
xem

ปัญหาบอกว่า xy ทั้งหมดอยู่ระหว่าง -1 ถึง 1 ไม่รู้จริง ๆ ว่าทำไม แต่ฉันเชื่อว่าคุณสามารถคูณทุกอินพุตด้วย 1e7 (เพื่อรักษาความแม่นยำ) ได้ผลลัพธ์ที่ถูกต้อง: D
Derek 朕會功夫

โซลูชันกราฟิกฉลาดมาก!
xnor

3

Python (65)

ดูเหมือนว่าผู้คนจะยอมแพ้ดังนั้นฉันจะโพสต์คำตอบของฉันเองในคำถามของฉัน

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

Xคือจำนวนเชิงซ้อนที่เป็นตัวแทนของจุดทดสอบและLเป็นรายการของสามคะแนนแต่ละจำนวนเชิงซ้อน

ก่อนอื่นฉันจะอธิบายเวอร์ชันของ golfed ที่น้อยลง

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)

เราเปลี่ยนประเด็นA,B,C,Xเพื่อให้Xเป็นจุดเริ่มต้นโดยใช้ประโยชน์จากเลขคณิตเชิงซ้อนในตัวของไพ ธ อน เราจำเป็นต้องตรวจสอบว่ามีจุดกำเนิดอยู่ในเปลือกนูนหรือไม่A,B,Cหรือไม่ สิ่งนี้เทียบเท่ากับจุดกำเนิดอยู่บนด้านเดียวกันเสมอ (ซ้ายหรือขวา) ของส่วนของเส้น AB, BC และ AC

ส่วนABมีต้นกำเนิดทางด้านซ้ายหากมีการเดินทางทวนเข็มนาฬิกาน้อยกว่า 180 องศาเพื่อรับจาก A ถึง B และทางขวาเป็นอย่างอื่น ถ้าเราพิจารณามุมa, bและcสอดคล้องกับจุดเหล่านี้หมายถึงนี้b-a < 180 degrees(มุมที่ถ่ายในช่วง 0-360 องศา) angle(B/A)=angle(B)/angle(A)ในฐานะที่เป็นตัวเลขที่ซับซ้อน นอกจากนี้ว่าสำหรับจุดในเขาครึ่งบนเครื่องบินซึ่งเราจะตรวจสอบผ่านangle(x) < 180 degreesimag(x)>0

ดังนั้นไม่ว่าแหล่งกำเนิดโกหกทางด้านซ้ายของ AB (A/B).imag>0จะแสดงเป็น การตรวจสอบว่าสิ่งเหล่านี้เท่ากันทุกคู่วงจรในA,B,Cบอกเราว่าสามเหลี่ยมABCมีต้นกำเนิด

ทีนี้เราจะกลับไปที่รหัสที่สมบูรณ์

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

เราสร้างวงจรแบบคู่ขึ้น(A-X,B-X,C-X)=(L[0]-X,L[1]-X,L[2]-X)มาโดยใช้ประโยชน์จากดัชนีรายการไพ ธ อนที่ล้อมรอบ ( L[-1]= L[2]) ในการตรวจสอบว่า Bools นั้นเป็นทั้งหมดTrue( 1) หรือทั้งหมดFalse( 0) เราได้เพิ่มพวกมันและตรวจสอบการหารได้ 3 ตามวิธีแก้ปัญหาที่หลากหลาย


2

Fortran - 232 218 195 174

กระหายเลือด ฟังก์ชั่นน่ากลัวเพราะความต้องการที่ข้อมูลถูกส่งไปยังมันและเราไม่สามารถประมวลผลล่วงหน้าได้

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

การลดลงของอักขระ 14 ตัวเป็นเพราะฉันลืมที่จะเล่นกอล์ฟชื่อฟังก์ชั่นจากการทดสอบของฉันทำงาน การลดลงอีกเนื่องจากการพิมพ์โดยนัยและลืมเปลี่ยนชื่อฟังก์ชั่น อักขระ 20 ตัวถัดไปออกเนื่องจากการอ่านในจุดเป็นอาเรย์เดียว โปรแกรมเต็มรูปแบบคือ

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

1
คุณสามารถทำให้สิ่งนี้สั้นลงได้เล็กน้อยโดยอาศัยการพิมพ์โดยนัยของ Fortran และใช้อาร์เรย์อินพุตเดียวที่มีตัวเลขทั้งหมด 8: 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);endฉันได้พยายามย่อให้สั้นลงอีกโดยใช้การทำงานของรายการ แต่น่าเสียดายที่ทำงานได้ไม่ดีนัก
Ventero

1
สั้นลงด้วยการกำจัดนิพจน์ย่อยทั่วไป: 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);endฉันหวังว่าฉันจะไม่ทำผิดพลาดใด ๆ ในการแปลงรูป! แม้ว่าดูเหมือนว่ารหัสต้นฉบับของคุณจะไม่ผ่านการทดสอบทั้งหมด
Ventero

@Ventero: ฉันไม่อยากจะเชื่อว่าฉันลืมที่จะละเมิดการพิมพ์โดยนัย :( ขอบคุณสำหรับความช่วยเหลือของคุณ!
Kyle Kanos

@Ventero: ดูเหมือนว่าคำตอบของฉันขึ้นอยู่กับทิศทางของสามเหลี่ยม Trueตัวอย่างแรกใน OP จะให้Falseถ้าฉันสลับBและCค่าของในขณะที่ให้Trueการปฐมนิเทศต้นฉบับ
Kyle Kanos

อาแน่นอนปัญหาเกิดขึ้นเมื่อ (ใช้สัญกรณ์อีกครั้งจากความคิดเห็นก่อนหน้าของฉัน) a < 0ซึ่งจะกลับสภาพที่คุณต้องทดสอบได้อย่างมีประสิทธิภาพ น่าเสียดายที่นี่ไม่สามารถแก้ไขได้ด้วยการห่อทุกอย่างไว้ในสถานะabsเดียวกับสภาพโดยนัยbและdมีสัญลักษณ์เดียวกับที่aหลงทาง สิ่งนี้สามารถแก้ไขได้โดยใช้บางสิ่งเช่น (อีกครั้งใช้เครื่องหมายและตัวแปรที่กำหนดไว้ล่วงหน้าอีกครั้งจากความคิดเห็นล่าสุดของฉัน) 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)- ซึ่งอาจจะสามารถเล่นกอล์ฟได้มากขึ้น
Ventero

2

MATLAB: 9!

ฉันไม่ได้เขียนที่นี่ทั้งหมด

inpolygon

สามารถถูกเรียกเช่น:

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

เอาต์พุตถูกกำหนดให้กับตัวแปรที่ชื่อ ans


ถ้าฉันต้องเขียนฟังก์ชั่นจริง ๆ มันอาจจะเป็นแบบนั้นก็ได้

function y=f(a,b,c,d)
inpolygon(a,b,c,d)

2
สามารถจะสั้นลงโดยใช้ฟังก์ชั่นการจัดการ: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]);}

อาจไม่เป็นตัวละครที่มีประสิทธิภาพเป็นวิธีการทางคณิตศาสตร์ แต่มันสนุกกับการใช้ห้องสมุด บังเอิญยังค่อนข้างช้า

การใช้ประโยชน์จาก "ไม่ต้องกังวลกับความเสถียรของตัวเลขหรือความแม่นยำจุดลอยตัว" - โชคไม่ดีที่GraphicsPathใช้ints ภายในดังนั้นค่าในช่วง -1 <f <1 สามารถมีค่าที่เป็นไปได้สามค่าเท่านั้น เนื่องจากการลอยมีเพียง 7 หลักของความแม่นยำฉันเพียงแค่คูณ 1e7 เพื่อเปลี่ยนเป็นตัวเลขทั้งหมด อืมข้าคิดว่ามันไม่ได้สูญเสียความแม่นยำเลย นอกจากนี้ยังเป็นการใช้ประโยชน์ในอีกทางหนึ่ง: ฉันอาจใช้ประโยชน์จากการเพิกเฉยต่อความแม่นยำและได้รับคำตอบที่ผิด

ถ้าฉันได้รับอนุญาตให้เพิกเฉยต่อค่าใช้จ่ายของตัวละครในการนำเข้าไลบรารี่149 (อย่างน้อยที่สุดSystem.LinqและSystem.Drawingเป็นมาตรฐานที่ดีสำหรับโครงการ WinForms ส่วนใหญ่ แต่System.Drawing.Drawing2Dอาจยืดออกไปหน่อย):

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]);}

โปรแกรมทดสอบ (ใช่แล้วมันน่าเกลียด):

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]);
    }
}

น่ารักใช้เครื่องมือวาดรูปเพื่อทำงาน
xnor

2

Haskell - 233 127

ใช้ผลิตภัณฑ์ข้ามตามที่อธิบายไว้ที่นี่ :

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

โซลูชันก่อนหน้านี้ถูกใช้งานโดยใช้พิกัด barycentricและสูตรที่อธิบายไว้ในคำตอบของ Stack Exchange :

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)

ทั้งฟังก์ชั่นgและhรับสี่คู่ซึ่งสิ่งแรกคือจุดที่จะทดสอบเพื่อรวมและส่วนที่เหลือเป็นพิกัดของจุดยอดของรูปสามเหลี่ยม

หากต้องการทดสอบด้วยอินพุตตัวอย่าง:

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]

วิธีแก้ปัญหาที่ไม่ดี:

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)

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

คัดลอกโดยตรงจากคำตอบของฉันไปยังคำถามอื่นนี้

ทดสอบในคอนโซล FireFox / FireBug

ส่งออกทั้งหมด 1 วินาที

;[
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)
]

ส่งออกทั้งหมด 0 วินาที

;[
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)
]

2

SmileBASIC, 111 100 ตัวอักษร

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

วาดรูปสามเหลี่ยมและตรวจสอบสีของพิกเซลที่จุด สามเหลี่ยมถูกปรับขนาดขึ้น 99999x และเลื่อนเพื่อให้จุดตรวจสอบอยู่ที่ (0,0) ก่อนที่จะถูกวาดเพื่อลดการสูญเสียอย่างแม่นยำ


2

ชุดประกอบ Intel 8087 FPU 222 220 ไบต์

ใช้ฮาร์ดแวร์ 8087 FPU เพื่อคำนวณเท่านั้น นี่คือรุ่นที่ไม่มีการประกอบ (ไม่มีการบรรจุในกรณีนี้ด้วย) เป็น MACRO (จะสำรองรหัสไบต์ฐานสิบหกไว้ให้คุณ 220):

; 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

คำอธิบาย

ใช้การกำหนดเพื่อคำนวณพื้นที่ของสามเหลี่ยม ABC จากนั้นสามเหลี่ยมที่เกิดขึ้นด้วยจุด X และจุดอีกสองจุดของสามเหลี่ยม ABC หากพื้นที่ของรูปสามเหลี่ยม ABC เท่ากับผลรวมของพื้นที่ของรูปสามเหลี่ยม XBC + AXC + ABX จุดนั้นจะอยู่ภายในรูปสามเหลี่ยม ผลลัพธ์ถูกส่งคืนเป็น ZF

มีระเบียบอะไรเกี่ยวกับเรื่องนี้

การดำเนินการทางคณิตศาสตร์และทศนิยมทั้งหมดดำเนินการในฮาร์ดแวร์ที่มีความแม่นยำเพิ่มขึ้น 80 บิต การเปรียบเทียบจุดลอยตัวสุดท้ายทำด้วยฮาร์ดแวร์ดังนั้นจะแม่นยำมาก

นอกจากนี้ยังใช้รีจิสเตอร์สแต็กของ 8087 ทั้งแปดในคราวเดียว

มีอะไรไม่เป็นระเบียบเกี่ยวกับเรื่องนี้

เนื่องจากจุดของรูปสามเหลี่ยมต้องเสียบกลับเข้าไปในสูตรหลายครั้งในระหว่างการคำนวณจึงต้องโหลดแต่ละตัวแปรในหน่วยความจำลงในสแต็กของ FPU ที่ลงทะเบียนครั้งละหนึ่งตามลำดับที่ถูกต้อง ในขณะที่สิ่งนี้สามารถสร้างแบบจำลองได้อย่างง่ายดายเหมือนฟังก์ชั่นในฐานะ MACRO แต่หมายความว่าโค้ดจะถูกขยายทุกครั้งที่แอสเซมบลีสร้างรหัสซ้ำซ้อน 41 ไบต์ถูกบันทึกโดยการย้ายส่วนรหัสซ้ำที่ซ้ำกันบางส่วนลงใน PROC อย่างไรก็ตามมันทำให้โค้ดอ่านน้อยลงดังนั้นรายชื่อข้างต้นจึงไม่มีมัน (ซึ่งเป็นสาเหตุที่มีการระบุว่า "ungolfed")

การทดสอบ

นี่คือโปรแกรมทดสอบโดยใช้ IBM DOS แสดงผลลัพธ์:

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,'$'

เอาท์พุต

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

1

C 414 (เดิมคือ 465)

แข็งแรงเล่นกอล์ฟ

#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");}

เพิ่มการประกาศฟังก์ชั่นดั้งเดิมสำหรับคำอธิบาย

/**
* 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);

เขียนใหม่เป็นฟังก์ชันที่มีชื่อ: อินพุตผ่าน stdin หนึ่งบรรทัดแต่ละบรรทัดหรือทั้งหมดในหนึ่งบรรทัดเว้นวรรค

#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");
}

3
คุณสามารถบันทึกไบต์โดยการกำจัดบรรทัดใหม่และช่องว่างที่ไม่จำเป็น นอกจากนี้คุณได้doubleกำหนดใหม่เป็นDแต่คุณยังคงใช้doubleในรหัส
gronostaj

1

Java, 149 ตัวอักษร

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;

การพิจารณาที่น่ากลัวฉันต้องเขียน "คณิตศาสตร์" ทุกเวลา. นี่คือโปรแกรมจริง:

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));
}
}

โดยที่ a คือ x ของจุด a, b คือ x ของจุด b, c สำหรับ x ของ c, d คือ y ของ a, e คือ y ของ b, f คือ y ของ c, และ x และ y เป็น x และ y y ของจุด บูลีน k พิจารณาว่าเป็นจริงหรือไม่


1
มีไว้100*เพื่ออะไร
xnor

1

JavaScript 125/198

หากมีการให้คะแนนใน 8 ข้อโต้แย้ง:

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}

หากมีการให้คะแนนในอาร์เรย์ 2 มิติ:

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}}

รหัสนี้ไม่ใช้คณิตศาสตร์เวกเตอร์แฟนซีใด ๆ แต่จะใช้เพียงเทคนิคพีชคณิตแบบง่ายๆเพื่อกำหนดว่าจุดนั้นอยู่ในรูปสามเหลี่ยมหรือไม่ สูตร:

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

ซึ่งบอกจุดที่อยู่ด้านข้างของบรรทัดมาจากการจัดเรียงใหม่คำจำกัดความของความชัน:

            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)

หากเราทดสอบทั้ง 3 ด้านทั้ง 3 ควรให้จำนวนที่มีเครื่องหมายเหมือนกันเฉพาะเมื่อจุดอยู่ภายในรูปสามเหลี่ยมเนื่องจากเราทดสอบรอบสามเหลี่ยม หากจุดอยู่ด้านข้างหนึ่งในการทดสอบควรกลับ 0

รหัสทดสอบ 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 ตัวอักษร (ไม่นับช่องว่างหรือแท็บ) นับหากแปลงเป็น 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 ตัวอักษรหากแปลงเป็น 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}

นั่นคือ "คณิตศาสตร์เวกเตอร์แฟนซี" ที่ฉันใช้: D (ไม่ใช่วิธีประสานงาน barycentric แฟนซีที่คนอื่นใช้) เช่นเดียวกับคำตอบที่ได้รับการโหวตบนคุณสามารถบันทึกไม่กี่ไบต์โดยใช้ ES6 d=(x,y,...)=>{...}และการกำหนดฟังก์ชั่นเช่น ในกรณีของคุณคุณสามารถประหยัดมากยิ่งขึ้นโดยใช้ CoffeeScript ซึ่งไม่จำเป็นต้องreturn: pastebin.com/RVFk1D5k ... และในกรณีใด ๆ คุณสามารถบันทึกหนึ่งไบต์โดยใช้แทน<1 ==0
Martin Ender

@ m.buettner: o ฉันคิดว่าสมการที่ฉันใช้นั้นไม่มีส่วนเกี่ยวข้องกับเวกเตอร์ (มาจากพีชคณิตแบบง่าย) แต่เห็นได้ชัดว่าพวกเขาทั้งคู่ให้สมการเดียวกัน คณิตศาสตร์เป็นสิ่งมหัศจรรย์
Derek 朕會功夫

1

R, 23

แรงบันดาลใจจากMATLAB ,

SDMTools::pnt.in.poly()

เรียกว่า like SDMTools::pnt.in.poly(point,triangle)ซึ่งpointเป็นเวกเตอร์ความยาว -2 และtriangleเป็นเมทริกซ์จุดยอด 3x2 SDMTools มีอยู่ใน CRAN


1

Mathematica, 38 ตัวอักษร

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

ตัวอย่าง:

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

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

(* จริง *)


เป็นมาตรฐานในการนับช่องว่างเป็นตัวอักษร แต่น่าจะเป็นที่นี่คุณสามารถลบออกได้โดยไม่ทำลาย
xnor

1
นอกจากนี้คุณต้องรับอินพุตและสร้างเอาต์พุตแทนการใช้ตัวแปรที่กำหนดไว้ล่วงหน้า คุณสามารถค้นหาคำตอบทางคณิตศาสตร์บางส่วนเพื่อดูว่าพวกเขาทำได้อย่างไร
xnor

0

C (gcc) , 108 ไบต์

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;}

ลองออนไลน์!

รับผลิตภัณฑ์ข้ามสามอย่างและส่งคืน1หากเครื่องหมายของส่วนประกอบไม่เปลี่ยนแปลง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.