スタートページJavaScriptライブラリ目次

幾何 JavaScript関数ライブラリ geo.js の利用解説書

ご利用にあたって

geoAtan2PI Math.atan のθ範囲変更
  θ = geoAtan2PI(x,y);  

θ = Math.atan(y/x) でのθをX軸から反時計回りに0≦θ<2πの範囲で求めます。
θ = atan2PI( 2, 1.732) = (1/3)π
θ = atan2PI(-2, 1.732) = (2/3)π
θ = atan2PI(-2,-1.732) = (4/3)π
θ = atan2PI( 2, 1.732) = (5/3)π

x= y= θ=rad (°)

geoRotation 点の回転
  rtn = geoRotation(xa, ya, t [, x0, y0]);  

点Aを、Oを中心に、X軸から逆時計回りに t(度)回転した点Bの座標を戻します。
 (x0,y0 を省略すると 0,0 になります。O点=原点)
  xb = rtn["xb"];  yb = rtn["yb"];

xa= ya= t= x0= y0=
rtn["xb"]= rtn["yb"]=
(補助)角度 t の変換
ラジアン 勾配

回転公式
  xb = (xa-x0)*cos(t) - (ya-y0)*sin(t) + x0;
  yb = (xa-x0)*sin(t) + (ya-y0)*cos(t) + y0;


geoLineExtend ベクトルの延長
  rtn = geoLineExtend(1, xa, ya, p [, x0, y0]);
  rtn = geoLineExtend(2, xa, ya, AB [, x0, y0]);  

ベクトルOAを延長したOBのB点の座標を戻します。
  O点=原点 (x0,y0 = 0)のとき省略できます。
 ptn = 1:d= = p    OB=OA * p
 ptn = 2:d= = AB  OB=OA * AB

ptn = 1 : xa= ya=  p= x0= y0= rtn["xb"]= rtn["yb"]=
ptn = 2 : xa= ya= AB= x0= y0= rtn["xb"]= rtn["yb"]=

geoLineDivide 線分の内外分点
  rtn = geoLineDivide(xa, ya, xb, yb, pa, pb);  

点Aからの距離:点Bからの距離=pa:pb の内分点 (xi,yi) と外分点 (xe,ye) を求めます。

xa= ya= xb= yb= pa= pb=
rtn["xi"]= rtn["yi"]= rtn["xe"]= rtn["ye"]=


geoLinePoint 線と直線の位置(中点、垂点)
  rtn = geoLinePoint(xa, ya, xb, yb, xc, yc);  

線分ABの中点D、点CのDの点対称点をE、
線分ABの点Cからの垂点F、点CのDの点対称点をGとします。
入力:A、B、Cの座標
出力:D、E、F、Gの座標
   AD、AFの長さ
   直線を px+qy+r = 0 としたときのAD、AFの p, q, r

xa= ya= xb= yb= xc= yc=
D点:rtn["xd"]= rtn["yd"]=
E点rtn["xe"]= rtn["ye"]=
CDの長さ:rtn["CD"]=
CDの式:px+qy+r=0:rtn["CDp"]= rtn["CDq"]= rtn["CDr"]=

F点:rtn["xf"]= rtn["yf"]=
G点:rtn["xg"]= rtn["yg"]=
CFの長さ:rtn["CF"]=
CFの式:px+qy+r=0:rtn["CFp"]= rtn["CFq"]= rtn["CFr"]=

geoLineCross 2線分の交差判定
  rtn = geoLineCross(xa, ya, xb, yb, xc, yc, xd, yd);  

直線ABとCDの交点Pの座標、線分ABとCDの交差判定(交わるか否か)をします。
  交点Pの座標:rtn["xp"], rtn["yp"]
  交差判定:rtn["cn"] = 1(交差する)/ 0(交差しない)
   ① 1 ② 0 ③ 0

xa= ya= xb= yb=
xc= yc= xd= yd=
rtn["xp"]= rtn["yp"]= rtn["cn"]=

一般形:rtn = geoTriSA(type, p1, p2, p3); 
  rtn = geoTriSA(3, AB, BC, CA)  // 3辺
  rtn = geoTriSA(2, AB, CA, A)   // 2辺夾角
  rtn = geoTriSA(1, BC, B, C)   // 2角夾辺

三角形の辺と内角の3つを与えて他の辺と内角と面積をを求めます。
   return [AB, BC, CA, A, B, C, S];
    AB = rtn["AB"];  A = rtn["A"];  S = rtn["S"];
 (角度はラジアンではなく度です。)

type=3: AB= BC= CA=
type=2: AB= CA= A=
type=1: BC= B= C=
rtn["AB"]= rtn["BC"]= rtn["CA"]=
rtn["A"]= rtn["B"]= rtn["C"]=
rtn["S"]=

三角形の頂点座標を与えて、辺長、内角、5心を得る
  rtn = geoTriVertex(xa,ya, xb,yb, xc,yc);  

[拡大図]
三角形の頂点座標 (xa,ya, xb,yb, xc,yc) を与えて、上図で示した諸元を戻します。
戻り値の形式は連想配列ですので、例えば「 var 面積 = rtn["S"] 」とします。

xa= ya=  xb= yb=  xc= yc= 


多角形の面積
  s = geoPolyS(x0,y0, x1,y1, …);  

自己交差を持たないn個の線分からなるn角形の頂点座標を与えて、面積 S を求めます。

x=
y=
S=

正多角形
  rtn = geoPolyRegA(n, a);  

正n角形の一辺の長さ a を与えて、諸元を求めます。

n= a=
φ= θ= r= R= S=

正多角形
  rtn = geoPolyRegR(n, R);  

正n角形の外接円の半径 R を与えて、諸元を求めます。

n= R=
φ= θ= a= r= S=

円と球
  rtn = geoCircleSphere(記号, 値);  

以下の任意の1つの値を与えて、他の4つを求めます。
  例:半径 = 2 を与える → rtn = geoCircleSphere("R", 2);

 記号 公式
 半径 R R
 円周 L 2*π*R
 円面積 S π*R2
 球面積 SS 4*π*R2
 球体積 V (4/3)*π*R3
記号= 値=
rtn["R"]= rtn["L"]= rtn["S"]= rtn["SS"]= rtn["V"]=

円と直線
  rtn = geoCircleLine(x0, y0, r, a, b, c);  

中心 (x0,y0)、半径 r の円と、直線 ax + by + c = 0 の距離 d と交点A、Bの座標
交点の個数を求めます。
 (交わらないときは、xa,ya, xb,yb = 0 を戻します)

x0= y0= r= a=  b= c= 
rtn["d"]= rtn["cn"]=
rtn["xa"]= rtn["ya"]=  rtn["xb"]= rtn["yb"]=

円と線分の交点
  rtn = geoCircleLineSeg(x0, y0, r, xa, ya, xb, yb);  

中心 (x0,y0)、半径 r の円と、2点A,Bを通る線分との垂直距離 d と交点C、Dの座標、 および、交点の個数 cn を求めます。
  ① C、Dあり cn = 2
  ② C、Dあり cn = 1
  ③ C、Dあり cn = 0
  ④ すべて0  cn = 0

x0= y0= r= xa= ya= xb= yb=
rtn["d"]= rtn["cn"]=
rtn["xc"]= rtn["yc"]=  rtn["xd"]= rtn["yd"]=

2円の交点
  rtn = geoCircle2(xa, ya, ra, xb, yb, rb);  

入力:中心(xa,ya), 半径 ra の円と、中心(xb,yb), 半径 rb の円
出力:AB 2円の中心の距離
   cn 交点の個数
     = 0 ra+rb < AB      互いに外部にあり公差しない
     = 0     AB < |ra-rb| 一方の円の内部に他方の円。交点なし
     = 1 ra+rb = AB      2円が接する
     = 2 それ以外       2円が重なる
  (cn ≠ 0 のとき、次の値を出力)
   xc, yc, xd, yd 交点C、Dの座標
    (C.Dの位置は逆になることもあります)
   CD 線分CDの長さ
   a, b, c 直線CDの方程式 ax + by + c = 0
   ta, tb 円中心と交点の角度
   Sa, Sb 重なった部分の面積

xa= ya= ra=  xb= yb= rb=
rtn["cn"]= rtn["AB"]=
rtn["xc"]= rtn["yc"]=  rtn["xd"]= rtn["yd"]=
rtn["CD"]=  rtn["a"]= rtn["b"]= rtn["c"]=
rtn["ta"]= rtn["tb"]=  rtn["Sa"]= rtn["Sb"]=

楕円
  rtn = geoEllips(x0, y0, rx, ry t);  

入力:中心(x0,y0), 半径 rx, ry, X軸との傾き t(度) の楕円
   (x-x0)2/rx2 + (y-y0)2/ry2 = 1 を (x0,y0) を中心に t 度回転
出力:wxx, wxy, wyy // 楕円の方程式
      // wxx*(x-x0)2 - 2wx(y-y0)(x-x0)*y + wyy*(y-y0)2 = 1;
   xa1,ya1, xa2,ya2, xb1,yb1, xb2,yb2  // A、A'、B、B' の座標
   xc1,yc1, xc2,yc2, xd1,yd1, xd2,yd2  // C、C'、D、D' の座標
   xf1,yf1, xf2,yf2           // 焦点 F、F' の座標

x0= y0= rx= ry= t=
rtn["wxx"]= rtn["wxy"]= rtn["wyy"]=
A:rtn["xa1"]= rtn["ya1"]=  rtn["xa2"]= rtn["ya2"]=
B:rtn["xb1"]= rtn["yb1"]=  rtn["xb2"]= rtn["yb2"]=
C;rtn["xc1"]= rtn["yc1"]=  rtn["xc2"]= rtn["yc2"]=
D:rtn["xd1"]= rtn["yd1"]=  rtn["xd2"]= rtn["yd2"]=
F:rtn["xf1"]= rtn["yf1"]=  rtn["xf2"]= rtn["yf2"]=
(補助)角度 t の変換
ラジアン 勾配

計算の概要


2次関数の標準二次形式化
  geoQuadStdTrace(表示場所, axx, ayy, axy, ax, ay, a1) 
  var [x0, y0, c, λ0, λ1, Axx, Axy, Ayx, Ayy]
    = geoQuadStdTrace(axx, ayy, axy, ax, ay, a1) 

一般的な二次曲線
  F(x,y) = axxx2 + ayyy2 + axyxy + axx + ayx + a1 = 0
を、中心を原点をするように平行移動した二次形式
  F(x,y) = axx(x-x0)2 + ayy(y-y0)2 + axy(x-x0)(y-y0) + c = 0
にします。

さらに、X = Axx(x-x0) + Axy(y-y0), Y = Ayx(x-x0) + Ayy(y-y0) として曲線の傾きを回転して軸に対称にした標準二次形式
  H(X,Y) = λ0X2 + λ1Y2 + c
に変換します。

曲線が楕円または双曲線のときだけを対象にします。入力データにより、放物線や直線、あるいは虚楕円、虚双曲線になることがありますが、対象にせず途中で打ち切ります。

入力データのチェック

曲線が楕円または双曲線のときだけを対象にします。かなり大雑把ですが、事前に次のチェックをします。
例えば axx = 0 のときは、楕円または双曲線にならないので、エラーとして次のステップには進みません。
 Trase のときは理由を表示して停止します。
 Return のときは、return [99999, 0,0,0,0,0,0,0,0] とします。

二次形式への変換

二次形式とは、1次の項をもたない2次関数のことです。二次曲線を原点が中心になるよう平行移動することに相当します。
一般の2次関数
  F(x,y) = axxx2 + ayyy2 + axyxy + axx + ayx + a1 = 0
を、x = xg - x0, y = yg - y0  (xg = x + x0, yg = y + x0) とすると、次のように変形します。
 F(xg,yg) = axxxg2 + ayyyg2 + axyxgyg + axxg + ay(yg+y0) + c
    = axx(x-x02) + ayy(y-y02 + axyxy
    + (2axxx0 + axyy0 + ax)xg
    + (2ayyy0 + axyx0 + ay)yg
    + axxx02 + ayyy02 + axyx0y0 + axx0 + ayy0 + a1  (この項を c とする)
    = 0
1次の項をなくすには、x0, y0 を次の連立方程式から求めます。
  xの項 2axxx0 + axyy0 + ax = 0
  yの項 2ayyy0 + axyx0 + ay = 0
ここでの戻り値:、x0,、y0、c
入力データがすでに二次形式になっている(ax = ay = 0)ときは、この処理は不要で、
  x0 = 0、y0 = 0、c = a1 になります。

標準二次形式への変換

標準二次形式とは、xyの項をもたない二次形式です。
  H(X,Y) = λ0X2 + λ1Y2 + c
    X = Axxx + Axyy
    Y = Ayxx + Ayyy
二次形式の曲線を直角座標系に描くと傾いています。これを回転しで座標系に平行にすることに相当します。
ここでの戻り値:λ0. λ1, Axx, Axy, Ayx, Ayy

●対称行列
  [x-x0.y-y0] ⎾axx  axy/2⏋ ⎾x-x0
         ⎿axy/2 ayy ⏌ ⎿y-y0
  = axx (x-x0)2 + ayy(y-y0)2 + (axy/2) (x-x0)(y-y0)
 の関係があります。この
  ⎾axx  axy/2⏋
  ⎿axy/2 ayy ⏌
 を 対称行列 といいます。

 axxayy - (axy/2)2 = 0 のときは、曲線が楕円、双曲線にならない(放物線、直線)ので、ここでは対象にしません。

●固有値λ
 標準二次形式は H(X,Y) = λ0 X2 + λ1 Y2 + c になります。
 説明を省略しますが、この係数λはの固有値になります。
    = │axx - λ  ayy/2│ = 0
        │axy/2  ayy - λ│
   (axx- λ)(ayy - λ) - (axy/2)2 = 0
   → λ2 - (axx + ayy) λ + (axxayy - (axy/2)2) = 0
 λに関する2次方程式なので、2つの解 λ = λ0、λ1 があります。
 (楕円のときは、2つの解は正の実数解。双曲線のときは正と負の実数解になります。)
 それにより、2つの標準二次形式が生成されます。
   λ0X2 + λ1Y2 + c = 0
   λ1X2 + λ0Y2 + c = 0
 これは、標準化するのに、右回りにするか左回りにするかに対応しており、本質的なものではありません。
 (ここでは、楕円のときは小さいほう、双曲線ではcと異符号のほうを λ0 としています。)

●(x,y)→(X,Y) 変換
  固有値がλのとき、固有ベクトルは、
  axx-λ, - axy/2
 で、その単位長は
  α = 1/√( (axx-λ)(ayy-λ) + axy2/4 )
 になので、次の変換式が成立します。
  X = α(axx-λ)(x-x0) + (axy/2)(y-y0))
  Y = α((axy/2)(x-x0) + (ayy-λ)(y-y0))
 ここで、
  Axx = α(axx-λ), Axy = α(axy/2)
  Ayx = α(axy/2), Ayy = α(ayy/2)-λ
 とすれば、次の変換式になります。
  X = Axx(x-x0) + Axy(y-y0)
  Y = Ayx(x-x0) + Ayy(y-y0)

関連情報

Trace のときは、単に解への経過を示すだけでなく、二次形式に関連する事項の諸値も表示します。

●XY軸
(二次曲線の傾きに対応した (X,Y) 座標系の軸)
  X = Axx(x-x0) + Axy(y-y0)
  Y = Axy(x-x0) + Ayy(y-y0)
 において
  X = 0 とすれば、Y軸:Axx(x-x0) + Axy(y-y0) = 0
  y = 0 とすれば、X軸:Ayx(x-x0) + Axx(y-y0) = 0
 になります。
 両軸は直交しており、二次曲線は両軸に対して対称になります。
 これらの直線式をFに代入すれば、二次曲線の端点(長半径の位置など)が求められます。

●正規化
 標準二次形式
  λ0 X 2 + λ1 Y 2 + c = 0
 を、次のように正規化します。
  ±(X/Px)2 ± (Y/Py)2 = 1
   (Px) = √(±c/λ0)、 Py) = √±(±c/λ1)  ±は( )が正になるよう調整)
 λが同符号(楕円)で C>0 のとき
  実数のX,Y が存在しない。虚楕円になります。
 λが同符号(楕円)で C<0 のとき
  (X/Px)2 + (Y/Py)2 = 1 になります。
   Y = 0 とすると X = ±Px X軸での端点(短・長径)
   X = 0 とすると Y = ±Px Y軸での端点
 λが異符号(楕円)で C<0 のとき
  (X/Px)2 ー (Y/Py)2 = 1 になります。
   Y = 0 とすると X = ±Px X軸での端点(グラフの存在範囲
 λが異符号(楕円)で C>0 のとき
  -(X/Px)2 + (Y/Py)2 = 1 になります。
   X = 0 とすると Y = ±Py Y軸での端点(グラフの存在範囲
 これらの端点に(X,Y)→(x,y)の変換を行えば、F(x,y) での端点になります。

●F(x,y)の偏微分と曲線の存在範囲
 F(x-x0, y-y0) = axx(x-x0)2 + ayy(y-y0)2 + axy(x-x0)(y-y0) + c = 0
 偏微分
  ∂F/∂x = 2axx(x-x0) + axy(y-y0)
  ∂F/∂y = 2ayy(y-y0) + axy(x-x0)
 曲線の存在範囲
  ∂F/∂x = 0 のとき
   2axx(x-x0) + axy(y-y0) = 0
  はX軸に平行になります。
   axy(y-y0) = -2axx(x-x0)
  をFに代入すれば、
   axx(1 + 4axxayy - 2axy)(x-x0)2 + c = 0
   → x-x0 = ±√{-c/axx(1 + 4axxayy - 2axy) }
  の2つになります。これがFの最大小値を与えるxの値です。
  これに、axy(y-y0) = -2axx(x-x0) による y がFの最大小値になります。
  ( { } < 0 になるときは、実根が存在せず、範囲は無限大になります。)
  同様に、∂F/∂y = 0 から、Fの最右左点が求められます。

ケース1

入力
  var [x0, y0, c, λ0, λ1, r]
   = geoQuadStdTrace(1,  1, 1, -3, -3, 0);
  //         axx ayy axy ax ay a1
出力
 x0 = 1; y0 = 1; c = -3;
 λ0 = 1,5; λ1 = 0.5;
 Axx = 0.707, Axy=0.707, Ayx = 0.707, Ayy=-0.707

ケース2

axx= ayy= axy= ax= ay= a1=