2つの三角形の交差点


19

2D平面上の4点を与えA, B, C, D、三角形OABとの交差領域の面積を計算しますOCD。ここOで、は平面の中心であり、座標は(0, 0)です。

(算術演算に関して)一定の時間の複雑さで実行されるアルゴリズムは推奨されますが、強制されません。

ルール

  • 各ポイントは2つの実数として表され、それらのXおよびY座標を示します。
    • オプションで、プログラミング言語(またはプログラミング言語のライブラリ)に組み込みPoint型または同等の型がある場合、Pointオブジェクトを入力として使用できます。
  • 入力は、以下を含むがこれらに限定されない形式で、4ポイントとして与えられます。
    • 8つの座標のリスト。
    • 4点のリスト。各点は任意の便利な形式で表すことができます。
    • 2点の2つのリスト。
  • ポイントの特定の順序(反時計回りまたは時計回り)を想定することはできません
  • ポイントOが入力として渡されると想定することはできません。言い換えれば、プログラムは外部からの入力を受け取って使用してはなりません。
  • すべてのポイントが異なると仮定することはできません。言い換えれば、三角形が縮退している可能性があります。そのケースも処理する必要があります(以下のテストケースを参照)
  • 絶対的または相対的な差は、以下のサンプルテストケースの差よりも小さくなければなりません。10-3

受賞基準

これはで、バイト単位の最短回答が勝ちです!

サンプルテストケース

Ax Ay Bx By Cx Cy Dx Dy area

5 1 1 3 -1 0 0 -1 0
5 1 1 3 -1 0 0 0 0
5 1 1 3 0 0 0 0 0
5 1 1 3 3 4 4 -3 4.50418
5 1 1 3 1 2 2 1 1.5
5 1 1 3 -2 5 4 -2 1.74829
5 1 1 3 -2 5 5 4 2.96154
5 1 1 3 3 5 5 4 1.88462
5 1 1 3 3 5 3 1 3.92308
5 1 1 3 3 5 4 -1 5.26619
5 1 1 3 5 1 4 -1 0
5 1 1 3 5 1 1 3 7
1 3 1 3 5 1 1 3 0
1 3 1 3 1 3 1 3 0
4 8 4 -1 -2 6 -2 -3 0

1.2 3.4 -0.3 4.2 5 7.6 -1.1 2.4 2.6210759326188535
3.1 0.6 0.1 7.2 5.2 0.7 0.9 8 9.018496993987977

誰でも必要な場合、最初のテストケースグループの出力は次のとおりです。

0
0
0
46375/10296
3/2
1792/1025
77/26
49/26
51/13
23345/4433
0
7
0
0
0

テストケースのイラスト画像5 1 1 3 3 4 4 -3(緑色の四辺形の領域が予想される出力です):

[ 画像]


テストケースの1つには8ではなく9つの入力があります。1.2 3.4 -0.3 4.2 5 3 7.6 -1.1 2.4 0
ケリーロウダー

1
@KellyLowder修正済み。
user202729

回答:


16

Wolfram言語(Mathematica)、55バイト

0&@@Area@BooleanRegion[And,Simplex[{0{,}}~Join~#]&/@#]&

オンラインでお試しください!

些細な答えから数バイト削り取った。

%@{{{5, 1}, {1, 3}}, {{3, 4}, {4, -3}}} yields 46375/10296 or 4.504176379

で置き換えるAreaDiscretizeRegion交差点が表示されます。

ここに画像の説明を入力してください

ちなみに、これは三角形だけでなく、どのシンプレックスでも機能します。

JungHwan Minのおかげで-1バイト

@ user202729の提案は4バイトを追加しましたが、縮退した三角形に対して0を生成します


1
ポリゴンもシンプレックスの代わりに使用できます
ケリーロウダー

1
もう一つのバイト:{{0,0}}まで{0{,}}(この作品に表現評価されるため{Times[0, {Null, Null}]}
JungHwan分

サンプルテストケースにリストされているこのテストケースでは不合格です。
user202729

これはTIOでは機能しないことを既に指摘しています。彼らがフードの下に何を持っているかわからない。
ケリーロウダー

1
2本の線の交点では機能しないことがわかります。そのテストケースをスキップするのは悪いことです。技術的には、これらは三角形ではありません。技術的なことをするつもりなら、最初の文だけでなく投稿のタイトルを変更する必要があるかもしれません。また、面積が1次元オブジェクトに対して定義されているかどうかについて、本当に難解な議論をすることもできますが、私はそうではありません。
ケリーロウダー

5

パイソン2 + PIL、341の 318 313 284 270バイト

Mr. XcoderのおかげでTIO -23バイトにPILをすぐに追加したDennisに
感謝

import PIL.Image as I,PIL.ImageDraw as D
l=[i*1000for i in[0,0]+input()+[0,0]]
z=zip(*[[i-min(t)for i in t]for t in l[::2],l[1::2]])
print sum(map(int.__mul__,*map(lambda i,c:D.Draw(i).polygon(c,1)or i.getdata(),map(I.new,'11',[[max(l)-min(l)]*2]*2),[z[:3],z[3:]])))/1e6

オンラインでお試しください!またはすべてのテストケースを試す

差異を計算するには、文字通り三角形を描き、両方の画像に描かれているピクセルの量を確認します。
このメソッドは、画像サイズを大きくすることで緩和される丸め誤差を挿入しました。

説明

#the image/triangles are enlarged to increase the precision
#a pair of zeros are inserted in the start and at the end, this way "l" will have all 6 points to draw the triangles 
l=[i*1000for i in[0,0]+input()+[0,0]]
#split the input in x and y, where x=l[::2] and y=l[1::2]
#get the smallest number on each list, that will be "0" if there is no negative number, to be used as offset.
#this will be used to overcome the fact that PIL won't draw on negative coords
#zip "x" and "y" lists, to create a list containing the points
z=zip(*[[i-min(t)for i in t]for t in x,y])
#create 2 (B&W) blank images
#where the size is the difference between the smallest and the largest coord.
map(I.new,'11',[[max(l)-min(l)]*2]*2)
#draw both triangles and return the pixel list of each image
map(lambda i,c:D.Draw(i).polygon(c,1)or i.getdata(),<result of previous line>,[z[:3],z[3:]])
#count the amount of overlapping pixels by summing the color of each pixel, if the pixel is "1" in both images, then the triangles are overlapping, then the amount of pixels is divided by the initial enlarging factor squared (1e6)
print sum(map(int.__mul__,*<result of previous line>))/1e6
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.