무작위로 생성된 내접삼각형 모델링

무작위로 생성된 내접삼각형 모델링

내가 모델링하고 있는 문제: 원 위에 세 개의 점이 무작위로 선택됩니다. 이 세 점으로 이루어진 삼각형이 원의 중심을 포함할 확률은 얼마입니까?

개념적 이해: 세 점 중 두 점을 고정하고 A와 B라고 한다고 가정합니다. 삼각형이 중심을 포함하려면 세 번째 점 C가 호 A'B' 내에 있어야 합니다. 여기서 A'와 B'는 A'와 B'의 이미지입니다. A점과 B점은 각각 180도 회전합니다.

내가 원하는 일: 무작위로 생성된 내접삼각형은 중심을 포함하면 녹색으로 채워지고, 중심을 포함하지 않으면 빨간색으로 채워집니다. 또한 실험적 확률을 계산하기 위해 성공 및 실패 횟수를 계속 집계하고 싶습니다.

여기에 이미지 설명을 입력하세요

몇 가지 핵심 사항\pgfextractx: 및 를 사용하여 각 점의 x 및 y 좌표에 액세스할 수 있습니다 \pgfextracty. 내 방법은 를 사용하여 점 C가 A와 B의 x 좌표와 y 좌표 사이에 있는지 테스트하는 것이었지만 \xintifboolexpr여기에는 결함이 있습니다.

최소한의 작업 예:

\documentclass{article}
\usepackage[left=2cm, right=2cm, top=2cm, bottom=1cm]{geometry}
\usepackage{amsmath,amsfonts,tikz,xintexpr,calc}

\newcommand\circletest{
\begin{tikzpicture}[scale=0.6]

    \newdimen{\tempxa}
    \newdimen{\tempya}
    \newdimen{\tempxb}
    \newdimen{\tempyb}
    \newdimen{\tempxc}
    \newdimen{\tempyc}

    \def\radius{2}
    \draw (0,0) coordinate (O);
    \draw (O) circle[radius=\radius];
    \draw (rnd*360:\radius) coordinate (A);
        \pgfextractx\tempxa{\pgfpointanchor{A}{center}}
        \pgfextracty\tempya{\pgfpointanchor{A}{center}}
    \draw (rnd*360:\radius) coordinate (B);
        \pgfextractx\tempxb{\pgfpointanchor{B}{center}}
        \pgfextracty\tempyb{\pgfpointanchor{B}{center}}
    \draw (rnd*360:\radius) coordinate (C);
        \pgfextractx\tempxc{\pgfpointanchor{C}{center}}
        \pgfextracty\tempyc{\pgfpointanchor{C}{center}}

    \xintifboolexpr { (((\tempxc > -\tempxa) && (\tempxc < -\tempxb)) || ((\tempxc > -\tempxb) && (\tempxc < -\tempxa))) && (((\tempyc > -\tempya) && (\tempyc < -\tempyb)) || ((\tempyc > -\tempyb) && (\tempyc < -\tempya)))} %%I know this is grotesque 
     {\filldraw[color=green!80!black!100, fill=green!15] (A) -- (B) -- (C) -- cycle;} %true
      {\filldraw[color=red!80!black!100, fill=red!15] (A) -- (B) -- (C) -- cycle;} %false

    \fill[black] (A) circle[radius=2pt];
    \fill[black] (B) circle[radius=2pt];
    \fill[black] (C) circle[radius=2pt];
    \fill[black] (O) circle[radius=2pt];

    \draw (A) node[below]{A};
    \draw (B) node[below]{B};
    \draw (C) node[below]{C};
\end{tikzpicture}}

\begin{document}

\foreach \x in {0,1,...,11}{
    \circletest
}


\end{document}

내가 겪고 있는 문제: 분명히 내 비교 연산자 \xintifboolexpr와 그 뒤에 오는 기괴한 코드가 문제입니다. 나는 점 C가 (-\tempax,-\tempay)과 사이의 원호를 따라 있는지 확인하는 더 간단한 방법을 찾고 있습니다 (-\tempbx,-\tempby).

편집하다: Sandy G의 제안에 따른 올바른 솔루션입니다.

\documentclass{article}
\usepackage[left=2cm, right=2cm, top=2cm, bottom=1cm]{geometry}
\usepackage{amsmath,amsfonts,tikz,xintexpr,calc}
\usepackage{xfp}

\newcommand\circletest{
\begin{tikzpicture}[scale=0.6]

    \pgfmathsetmacro{\rndA}{rnd*360}
    \pgfmathsetmacro{\rndB}{rnd*360}
    \pgfmathsetmacro{\rndC}{rnd*360}

    %defining x and y coordinates of each point

    \def\radius{2}
    \def\xa{\fpeval{\radius*cosd(\rndA)}}
    \def\ya{\fpeval{\radius*sind(\rndA)}}
    \def\xb{\fpeval{\radius*cosd(\rndB)}}
    \def\yb{\fpeval{\radius*sind(\rndB)}}
    \def\xc{\fpeval{\radius*cosd(\rndC)}}
    \def\yc{\fpeval{\radius*sind(\rndC)}}

   %calculating side lengths of triangle
   \def\A{\fpeval{sqrt((\xb-\xc)^2 + (\yb-\yc)^2)}}
   \def\B{\fpeval{sqrt((\xa-\xc)^2 + (\ya-\yc)^2)}}
   \def\C{\fpeval{sqrt((\xa-\xb)^2 + (\ya-\yb)^2)}}

   %calculating angles of triangle
   \def\angleA{\fpeval{acosd((\B^2 + \C^2 -\A^2)/(2*\B*\C))}}
   \def\angleB{\fpeval{acosd((\C^2 + \A^2 -\B^2)/(2*\C*\A))}}
   \def\angleC{\fpeval{acosd((\A^2 + \B^2 -\C^2)/(2*\A*\B))}}

   %defining some coordinates
    \draw (0,0) coordinate (O);
    \draw (O) circle[radius=\radius];
    \draw (\xa,\ya) coordinate (A);
    \draw (\xb,\yb) coordinate (B);
    \draw (\xc,\yc) coordinate (C);

   %test if center is in circle
    \xintifboolexpr{((\angleA < 90) && (\angleB < 90)) && (\angleC < 90)}
     {\filldraw[color=green!80!black!100, fill=green!15] (A) -- (B) -- (C) -- cycle;} %true
     {\filldraw[color=red!80!black!100, fill=red!15] (A) -- (B) -- (C) -- cycle;} %false

   %Drawing points on top of line
    \draw[fill=black] (\xa,\ya) circle(1.5pt);
    \draw[fill=black] (\xb,\yb) circle(1.5pt);
    \draw[fill=black] (\xc,\yc) circle(1.5pt);
    \draw[fill=black] (O) circle(1.5pt);

\end{tikzpicture}}

\begin{document}

\foreach \x in {0,1,...,30}{
    \circletest
}

\end{document}

답변1

도서관 을 이용할 수 있고 calc,이 처방전, 이는 귀하의 것과 매우 유사하지만 약간 더 짧을 수도 있습니다. 라이브러리를 사용하면 calc새로운 차원을 도입하는 것을 피할 수도 있습니다. a를 정의하면 picTi를 사용할 수 있다는 장점이 있습니다.케이Z 원하는 방식으로 그림을 배열합니다.

\documentclass{article}
\usepackage[left=2cm, right=2cm, top=2cm, bottom=1cm]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
What is the probability for the triangle containing the origin? Without loss of
generality we can take the angle of $A$ to be 0 (because one can rotate the
setup without changing the probability). Then the angle of $B$, $\beta$ can be
chosen to be between $0$ and $\pi$ (because one can reflect the setup at the
$x$--axis without changing the probability). Then the angle of $C$, 
 $\gamma$, needs to satisfy
\[ \pi<\gamma<\pi+\beta \] 
for the center to be inside the triangle, see Figure~\ref{fig:derivation}.
As $\beta$ scans the domain $[0,\pi]$, the probability for a triangle with
corners at random positions of the circle enclosing the center of the circle is
$1/4$. 
\begin{figure}[ht]
\centering
\begin{tikzpicture}[dot/.style={circle,inner sep=1pt,fill},
    declare function={rr=2.5;}]
 \begin{scope}
  \draw (0,0) circle[radius=rr] (0,0) -- (rr,0) node[dot,label=right:$A$]{};
  \pgfmathsetmacro{\rndB}{rnd*90}
  \draw (1,0) arc[start angle=0,end angle=\rndB,radius=1] 
    node[midway,anchor=180+\rndB/2,circle]{$\beta$}
  (0,0) -- (\rndB:rr) node[dot,label={[anchor=\rndB+180]:$B$}]{};
  \draw[dashed] (180+\rndB:rr) -- (0,0) -- (180:rr);
  \draw[blue,thick] (180:rr) arc[start angle=180,end angle=180+\rndB,radius=rr]
  node[midway,anchor=\rndB/2,circle,align=right]{allowed\\ positions\\ for $C$};
 \end{scope}
 %
 \begin{scope}[xshift=2.8*rr*1cm]
  \draw (0,0) circle[radius=rr] (0,0) -- (rr,0) node[dot,label=right:$A$]{};
  \pgfmathsetmacro{\rndB}{90+rnd*90}
  \draw  (1,0) arc[start angle=0,end angle=\rndB,radius=1] 
    node[midway,anchor=180+\rndB/2,circle]{$\beta$}
    (0,0) -- (\rndB:rr) node[dot,label={[anchor=\rndB+180]:$B$}]{};
  \draw[dashed] (180+\rndB:rr) -- (0,0) -- (180:rr);
  \draw[blue,thick] (180:rr) arc[start angle=180,end angle=180+\rndB,radius=rr]
  node[midway,anchor=\rndB/2,circle,align=right]{allowed\\ positions\\ for $C$};
 \end{scope}
\end{tikzpicture}
\label{fig:derivation}
\end{figure}

\begin{figure}[ht]
\centering
\begin{tikzpicture}[pics/circletest/.style={code={
        \tikzset{circletest/.cd,#1}%
        \def\pv##1{\pgfkeysvalueof{/tikz/circletest/##1}}%
        \draw (0,0) coordinate (O) circle[radius=\pv{r}];
        \pgfmathsetmacro{\rndA}{rnd*360}
        \pgfmathsetmacro{\rndB}{rnd*360}
        \pgfmathsetmacro{\rndC}{rnd*360}
        \path (\rndA:\pv{r}) coordinate[label={[anchor=\rndA+180]:$A$}] (A)
         (\rndB:\pv{r}) coordinate[label={[anchor=\rndB+180]:$B$}] (B) 
         (\rndC:\pv{r}) coordinate[label={[anchor=\rndC+180]:$C$}] (C);
        \draw let \p1=(A),\p2=(B),\p3=(C),\p0=(O),
         \n1={(\x0-\x2)*(\y1-\y2)-(\x1-\x2)*(\y0-\y2)},
         \n2={(\x0-\x3)*(\y2-\y3)-(\x2-\x3)*(\y0-\y3)},
         \n3={(\x0-\x1)*(\y3-\y1)-(\x3-\x1)*(\y0-\y1)}
         in \pgfextra{\pgfmathtruncatemacro\itest{%
            ((\n1 < 0) || (\n2 < 0) || (\n3 < 0)) &&
            ((\n1 > 0) || (\n2 > 0) || (\n3 > 0))}}
         \ifnum\itest=0
          [color=green!80!black!100, fill=green!15] (A) -- (B) -- (C) -- cycle
         \else
          [color=red!80!black!100, fill=red!15]  (A) -- (B) -- (C) -- cycle
         \fi;
        \fill (O) circle[radius=1pt] node[below]{$O$}; 
    }},circletest/.cd,r/.initial=1]
 \path foreach \X in {1,...,5}
 {  foreach \Y in {1,...,5} {(3*\X,3*\Y) pic{circletest}}}; 
\end{tikzpicture}
\end{figure}

\end{document}

여기에 이미지 설명을 입력하세요

교차점을 기반으로 한 대안 제안입니다. 중심에서 원을 벗어나는 광선을 구성합니다. 삼각형과의 교점 개수가 짝수이면 중심은 삼각형의 외부에 있고, 그렇지 않으면 내부에 있습니다.

\documentclass{article}
\usepackage[left=2cm, right=2cm, top=2cm, bottom=1cm]{geometry}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}[pics/circletest/.style={code={
        \tikzset{circletest/.cd,#1}%
        \def\pv##1{\pgfkeysvalueof{/tikz/circletest/##1}}%
        \draw (0,0) coordinate (O) circle[radius=\pv{r}];
        \pgfmathsetmacro{\rndA}{rnd*360}
        \pgfmathsetmacro{\rndB}{rnd*360}
        \pgfmathsetmacro{\rndC}{rnd*360}
        \path (\rndA:\pv{r}) coordinate[label={[anchor=\rndA+180]:$A$}] (A)
         (\rndB:\pv{r}) coordinate[label={[anchor=\rndB+180]:$B$}] (B) 
         (\rndC:\pv{r}) coordinate[label={[anchor=\rndC+180]:$C$}] (C);
        \path[name path=triangle] (A) -- (B) -- (C) -- cycle;
        \path[name path=ray,overlay] (O) -- ({180+(\rndA+\rndB+\rndC)/3}:1.5*\pv{r});
        \draw[name intersections={of=triangle and ray,total=\t}]
         \ifodd\t
          [color=green!80!black!100, fill=green!15] (A) -- (B) -- (C) -- cycle
         \else
          [color=red!80!black!100, fill=red!15]  (A) -- (B) -- (C) -- cycle
         \fi;
    }},circletest/.cd,r/.initial=1]
 \path foreach \X in {1,...,5}
 {  foreach \Y in {1,...,5} {(3*\X,3*\Y) pic{circletest}}}; 
\end{tikzpicture}
\end{document}

여기에 이미지 설명을 입력하세요

이 접근 방식은 교차점의 정확성에 의해 제한되며 삼각형이 얇아지면(즉, 기본적으로 선인 경우) 실패할 수 있습니다.

PS 이러한 분포는 실제 확률과 일치합니다.

여기에 이미지 설명을 입력하세요

답변2

실험적 확률에 대한 호기심을 충족시키기 위해 에서 이 작업을 수행했습니다 metapost. 이론적 확률(예: 1/4)을 소수점 이하 3자리까지 일관되게 얻으려면 약 100,000개의 삼각형이 필요한 것 같습니다. 결과를 인쇄하기 위해 그리기 명령에 주석을 달면 1,000,000번 실행하는 데 몇 초 밖에 걸리지 않습니다. 1mm 원에 20,000개의 내접삼각형을 만드는 출력의 일부:

여기에 이미지 설명을 입력하세요 다음으로 실행 lualatex:

\documentclass{article}
\usepackage{luamplib}
\usepackage{geometry}
\mplibnumbersystem{double}
\mplibtextextlabel{enable}
\mplibcodeinherit{enable}
\begin{document}
\begin{mplibcode}
    vardef triarray(expr r,n)=
        save x,tmp,width;
        width:=\mpdim{\linewidth} div r;
        count:=0;
        tot:=n;
        for j=0 upto n:
            % for the grid
            drawoptions(withpen pencircle scaled .1bp shifted ((r+.1)*(j mod width),-(r+.1)*(j div width)));
            for i=1 upto 3: x[i]:=uniformdeviate(8); endfor;
            % sort vals, probably didn't need to, but made things tidier.
            if x1>x2: 
                tmp:=x1; x1:=x2; x2:=tmp; 
            fi;
            if x2>x3:
                tmp:=x2; x2:=x3; x3:=tmp;
                if x1>x2:
                    tmp:=x1; x1:=x2; x2:=tmp; 
                fi;
            fi;
            % end sort
            % points on a circle in mp are mapped to the interval [0,8] with 0->0 and 8->360
            % reflected points rather than rotating arc
            if ((x1+4) mod 8>x2) and ((x1+4) mod 8<x3) and ((x3+4) mod 8>x1) and ((x3+4) mod 8<x2):
                fill fullcircle scaled r withcolor .2[white,green];
                count:=count+1;
            else:
                fill fullcircle scaled r withcolor .2[white,red];
            fi;
            % uncomment below for the triangles
            draw for i=1 upto 3: point x[i] of (fullcircle scaled r)-- endfor cycle; 
        endfor;
    enddef;
    beginfig(0);

    triarray(1mm,20000);

    endfig;
\end{mplibcode}
\begin{mplibcode}
beginfig(1);
        picture p; string s;
        s="$\frac{"&decimal(count)&"}{"&decimal(tot)&"}="&decimal(count/tot)&"$";
        p= s infont defaultfont scaled defaultscale;
        draw p;
endfig;
\end{mplibcode}
\end{document} 

관련 정보