うしブログ

うしブログ

趣味で運営する、GeoGebraの専門ブログ。

(作業メモ)StartPoint要検証(2行の場合;テキスト変更時未定義問題)

(要修復)ToggleButton・RollPolygonWithoutSlipping・貯金時計・直感力トレーニング

正四面体に4つの球を内接させる

課題

正四面体を作成する。下図のように、その正四面体に内接し、互いに外接する4つの球を描け。

f:id:usiblog:20191128230003p:plain

 

見本アプレット

https://www.geogebra.org/m/xgbxzwgq

今回は、まずは3面に内接するように球を作成し、パラメータを調節することで、球同士を外接させる、というアプローチで作成してみた。

 

作成手順

正四面体を作成する

自由な点A,Bを、グラフィックスビュー1上に作成する。

正四面体の底面となる正三角形bottomを、以下の定義で作成する*1

bottom = Element[{Polygon[A, B, 3, xOy平面]}, 1]

f:id:usiblog:20191128221841p:plain

 

底面bottomの3頂点からなるリストbottomVerticeを、以下の定義で作成する。

bottomVertice = {Vertex[bottom]}

f:id:usiblog:20191128222020p:plain

 

底面bottomの重心bottomCentroidを、以下の定義で作成する。

bottomCentroid = Centroid[bottom]

f:id:usiblog:20191128222123p:plain

 

正四面体tetraを、以下の定義で作成する*2

tetra = Element[{Tetrahedron[bottom, true]}, 1]

f:id:usiblog:20191128222405p:plain

 

正四面体tetraの頂点Topを、以下の定義で作成する。

Top = Translate[bottomCentroid, Vector[(0, 0, Height[tetra])]]

正四面体tetraの4頂点からなるリストtetraVerticeを、以下の定義で作成する。

tetraVertice = Join[{bottomVertice, {Top}}]

f:id:usiblog:20191128222513p:plain

4つの球を作成する

正四面体tetraの4面のそれぞれの重心からなるリストcentroidsを、以下の定義で作成する。

centroids = {Centroid[Polygon[Element[tetraVertice, 2], Element[tetraVertice, 3], Element[tetraVertice, 4]]], Centroid[Polygon[Element[tetraVertice, 3], Element[tetraVertice, 4], Element[tetraVertice, 1]]], Centroid[Polygon[Element[tetraVertice, 4], Element[tetraVertice, 1], Element[tetraVertice, 2]]], Centroid[Polygon[Element[tetraVertice, 1], Element[tetraVertice, 2], Element[tetraVertice, 3]]]}

f:id:usiblog:20191128222811g:plain

 

頂点と、対面の重心とを結んだ線分のリストsegsを、以下の定義で作成する。

segs = Zip[Segment[α, β], α, tetraVertice, β, centroids] 

f:id:usiblog:20191128223042g:plain

 

数値オブジェクトparamを、範囲0〜1で作成し、スライダーを作成する。

パス・パラメータがparamであるような、segs上の点リストcoresを、以下の定義で作成する。

cores = Zip[Point[γ, param], γ, segs]

f:id:usiblog:20191128223400g:plain

 

球の半径radiusは、以下のように表されるので、これを作成する。

radius = z(Element[cores, 1])

4つの球リストsprsを、以下の定義で作成する。

sprs = Zip[Sphere[δ, radius], δ, cores]

f:id:usiblog:20191128224010g:plain

 

球同士が外接するときのparamの値を求める

球同士が外接するときのparamの値を求めて、paramをその値にすれば、目的の図を描くことができる。その値は、計算によって求めることも可能だが、今回はせっかくなので、GeoGebraに計算してもらおう。

 

点A側の球Element[sprs, 1]上の点のうち、点B側の球の中心Element[cores, 2]に最も近い点Pを、以下の定義で作成する。

P = ClosestPointRegion[Element[sprs, 1], Element[cores, 2]]

点B側の球Element[sprs, 2]上の点のうち、点A側の球の中心Element[cores, 1]に最も近い点Qを、以下の定義で作成する。

Q = ClosestPointRegion[Element[sprs, 2], Element[cores, 1]]

球同士が外接するならば、Distance[P,Q]は0である。

f:id:usiblog:20191128224838g:plain

 

paramとDistance[P,Q]との関係を調べよう。そのために、x軸にparam、y軸にDistance[P,Q]をとったときのグラフを考えよう。当該グラフ上の点graphPointは、

graphPoint = (param, Distance[P, Q])

と表せる。

Locus[graphPoint,param]

によって、グラフを描いてみると、下図のようになる。

f:id:usiblog:20191128225330g:plain

param = 0.53あたりで、球が外接することがわかる。証明は省略するが、paramが0から0.53あたりまで増加するに伴って、Distance[P, Q]は単調減少する。そこで、今回は、これを利用して、球が外接するときのparamの値を計算することにしよう。

 

graphPointの定義式を、paramに依存するオブジェクト名を用いずに、直接paramを用いて表すと、以下のようになる(graphPointNested)。

graphPointNested = (param, Distance[ClosestPointRegion[Element[Zip[Sphere[δ, z[Element[Zip[Point[γ, param], γ, segs], 1]]], δ, Zip[Point[γ, param], γ, segs]], 1], Element[Zip[Point[γ, param], γ, segs], 2]], ClosestPointRegion[Element[Zip[Sphere[δ, z[Element[Zip[Point[γ, param], γ, segs], 1]]], δ, Zip[Point[γ, param], γ, segs]], 2], Element[Zip[Point[γ, param], γ, segs], 1]]])

param=0におけるgraphPointの値は、graphPointNestedの定義式における「param」を、「0」に置換することによって得られる(graphPoint00)。

graphPoint00 = (0, Distance[ClosestPointRegion[Element[Zip[Sphere[δ, z[Element[Zip[Point[γ, 0], γ, segs], 1]]], δ, Zip[Point[γ, 0], γ, segs]], 1], Element[Zip[Point[γ, 0], γ, segs], 2]], ClosestPointRegion[Element[Zip[Sphere[δ, z[Element[Zip[Point[γ, 0], γ, segs], 1]]], δ, Zip[Point[γ, 0], γ, segs]], 2], Element[Zip[Point[γ, 0], γ, segs], 1]]])

同様に、param=0.5におけるgraphPointの値をもつ点として、graphPoint05を作成する。

graphPoint05 = (0.5, Distance[ClosestPointRegion[Element[Zip[Sphere[δ, z[Element[Zip[Point[γ, 0.5], γ, segs], 1]]], δ, Zip[Point[γ, 0.5], γ, segs]], 1], Element[Zip[Point[γ, 0.5], γ, segs], 2]], ClosestPointRegion[Element[Zip[Sphere[δ, z[Element[Zip[Point[γ, 0.5], γ, segs], 1]]], δ, Zip[Point[γ, 0.5], γ, segs]], 2], Element[Zip[Point[γ, 0.5], γ, segs], 1]]])

 

求めるparamの値は、Line[graphPoint00, graphPoint05]とx軸との交点AnsPointの、x座標の値に等しい。

AnsPoint = Intersect[Line[graphPoint00, graphPoint05], x軸]

 

ボタンを作成し、On Click スクリプトに、以下を記述する。

SetValue[param,x(AnsPoint)]

ボタンをクリックすると、4つの球が互いに外接するように、paramの値が調整される。

 

*1:このように、bottomは、{}で囲んでリストにして、その第一要素として定義している。これをしないと、正三角形の線分が自動的に作成され、数式ビューがごちゃつく。そのため、できるだけオブジェクトの数を少なくして、数式ビューの見通しをよくする趣旨で、このような処理をしている。

*2:これも、リストオブジェクトとして作成して、その第一要素として呼び出すことで、辺、面オブジェクトが大量に自動生成されることによる、数式ビューのごちゃつきを回避している。

(お遊び記事)もし「1+1=0を弁護しなさい」と言われたら?

くだらない記事は、いくらでも書けますね(笑)

 

 

有利な前提を持ち出す

・実はこれはベクトルの演算でして、長さ1のベクトルと、長さ1のベクトルを足したんです。今回は向きがちょうど反対だったので、0になったんです。

・例えば、あなたが僕にペンを1円で売ったとしましょう。売上1円ですね?僕はそのペンをあなたに1円で売ります。売上1円ですね?2人からなる経済全体があげた売上合計は1+1です。しかし、資産が増えたわけではありません。このように、1+1が0になる場合も十分に考えられるところ、彼はそういった場合を念頭に発言したのです。

・論理学においては、false⇒1+1=0はtrueであるとされております。したがって、1+1が0であるというだけで、直ちに誤りであると断ずるのは不当であります。彼が何を前提として、このような発言をしたのか、精査しないことには、何も分からないということです。

・ここにいう1+1というのは、通常の意味(1に1を加えるという計算)ではなく、数量0を表す呼称としての「いちぷらすいち」であります。彼は幼い頃から、0のことを1+1と呼び習わしています。彼の発言は、「1+1といえば0のことだよね」という意味であり、決して数学的計算とその結果との関係を言ったのではありません。

 

主観論に持ち込む

・数学では1+1は2なのかもしれませんが、彼にとっては1+1は0なんです。一個人の発言なのだから、その個人の思想や主観を反映しているのは当然であり、それは尊重されるべきです。

 

誤りは認めたうえで擁護する

・2進法で計算していたのですが、紙面が足りず1の位しか書けなかったんです。

・2を5万や10万と間違えたならともかく、0と間違えたというのですから、とりたてて非難するほどのことでもないですよね。

・確かに彼の発言は誤っていますが、その当時、彼は何者かによって、無理矢理に酒を大量に飲まされており、自分の発言が正しいか誤っているかについて、正常な判断能力を有していませんでした。したがって、そんな彼を責めることはできません。

 

開き直る

・たしかに1+1は0ではありませんが、彼がその点について誤っていたとして、一体誰が損をしたというのでしょうか。むしろ、彼の発言は、1+1が0ではないということを公衆に再認識させ、数と演算の概念について再考する機会を与えるものであり、学問的寄与が認められるのではないでしょうか。