• ベストアンサー

線対称な直線を求めたい

3本の直線があります。 SI=a1x+b1y+c1 SJ=a2x+b2y+c2 SK=a3x+b3y+c3 SKを基準とし、SJに対称なSIを求めるにはどうすればよいでしょうか? SIのa1,b1,c1の求め方を教えて下さい。 どうぞよろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • oze4hN6x
  • ベストアンサー率65% (26/40)
回答No.1

まずは、SJとSKの交点の座標(x0,y0)を求めて、それが原点になるように平行移動をします。すると直線の方程式は SI: a1x + b1y = 0 SJ: a2x + b2y = 0 SK: a3x + b3y = 0 となります。求めるべきSIの式は a1(x+x0) + b1(y+y0) = 0 で与えられますから、問題はa1とb1を求めることに帰着されます。 それぞれの直線の法線ベクトルは SI: n1 = (a1, b1) SJ: n2 = (a2, b2) SK: n3 = (a3, b3) ですから、n1 は n2 に関して n3 と対称なベクトルとして求めることができます。 n2 とx軸がなす角度をθとすると、n3 を-θだけ回転し、x軸に関して対称に折り返し、+θだけ回転したものが n1 です。したがって、θ回転行列を R(θ), x軸に関する折り返し行列を X とすると n1 = R(θ)XR(-θ)n3 となります。この計算は参考URLの通りです。θについては (cosθ,sinθ) = C2(a2, b2), C2 = (a2^2+b2^2)^(-1/2) ですから、これで n1 = (a1, b1) が計算できて、答えが得られることになります。

参考URL:
http://bit.ly/1wcaHAu
rechirin
質問者

補足

すいません。 何かが違います・・ 教えて下さい。 Θを求める計算 C2=(a2^2+b2^2)^(-1/2) ↓ Th = -Math.Sqrt(a2 * a2 + b2 * b2); http://bit.ly/1wcaHAuの x=cosΘ^2-sinΘ^2 y=2sinΘcosΘ x0=2sinΘcosΘ y0=sinΘ^2-cosΘ^2 とすると x = Math.Cos(Th) * Math.Cos(Th) - Math.Sin(Th) * Math.Sin(Th); y = 2 * Math.Sin(Th) * Math.Cos(Th); x0 = 2 * Math.Sin(Th) * Math.Cos(Th); y0 = Math.Sin(Th) * Math.Sin(Th) - Math.Cos(Th) * Math.Cos(Th); としたのですが、何か間違っているでしょうか?  本当に申し訳ありません。 どうぞよろしくお願い致します。

その他の回答 (3)

  • oze4hN6x
  • ベストアンサー率65% (26/40)
回答No.4

-1をかけるのは必要ですね。私が間違っていました。すみません。 atan2でうまく行くようでしたらそれでもよいのでしょう。プログラミングの問題ということであれば、初めから違ったアプローチになります。カテゴリを変えて質問されると異なった回答が得られるでしょう。実際、もっと効率がよく一般性の高い方法があります。ただし、私が今回用いた数学が難しいと感じられるようですと、そうした方法もまた難しいかもしれません。

rechirin
質問者

補足

先日の質問も含めて本当にありがとうございました。 カテゴリ選びは今後気を付けます。 数学系の問題だと思ったのですが、 結果、自分の扱える範囲を超えてしまったようです。 今後もこのような問題にあたることが多いと思いますので 数学を勉強したいと思います。 本当にありがとうございました。

  • oze4hN6x
  • ベストアンサー率65% (26/40)
回答No.3

SJ, SKの角度とはどの角度なのか不明 Math.Atan2が何を求める関数か不明 ・・・なのではっきりとしたことは答えられません。 後者が単純に arctan であるとすると、No. 2補足コメントのような方法ではうまく行く場合も、うまく行かないこともあります。a_n, b_n の正負による場合分けが必要になるでしょう。(・・・私はそのような面倒な場合分けは間違いの元なので考えたくありません。そこで回答に示したような別の方法を取っているわけです。) atan2が直線がx軸の正の向きとなす角度(0-π)を与えるような便利な関数であるとすると、No. 2補足コメントで意図されていることは有効でしょうね。その場合には、a1の最後に -1 をかけているのは不要に見えます。ただし、これは atan2がどのような関数であるかに依るので、間違いではないかもしれません。 ちなみに、数学の問題としては、atan2が返す値をどうやって求めるのかに答えてないので失格です。私の回答は、場合分けもせず、そのような関数も使わないでa2,b2等だけで答えを表現することを意図しています。

rechirin
質問者

補足

まず、何度もご返答、本当にありがとうございます。 atan2については、 http://msdn.microsoft.com/ja-jp/library/system.math.atan2(v=vs.110).aspx -180~180で表現できるので大丈夫かと思いました。 (関数が賢いようで、SK=-170 SJ=150でも正しく答えが出ているようです。) -1をかけるのは、実は私も気になっているのですが、y=axの形に直し、CADで 絵を描いてみると-1をかけないとどうしても、ax+by=0の形に合わなくなってしまいます。 ともあれ、おっしゃるとおり便利関数に頼っている時点で、数学ではお話に ならないと思います。 数式は理解できなかったのですが、角度の求め方だけ使わせて頂きます。 本当にありがとうございました。 答えが出るようですので、もう少しで閉めさせて頂きます。 …もう少し数学を勉強します・・

  • oze4hN6x
  • ベストアンサー率65% (26/40)
回答No.2

あなたの表記で書くと、 (a2^2+b2^2)^(-1/2) = 1 / Math.Sqrt(a2 * a2 + b2 * b2) です。つまり、 cosθ = a2 / Math.Sqrt(a2 * a2 + b2 * b2) sinθ = b2 / Math.Sqrt(a2 * a2 + b2 * b2) です。n2をその長さで割ると、n2と同じ向きの単位ベクトルが得られますね。その単位ベクトルのx, y座標として、cosθ, sinθが得られるということです。

rechirin
質問者

補足

すいません。いろいろ説明いただいた式がぜんぜん理解できなかったのですが、 よーく冒頭の >n2 とx軸がなす角度をθとすると、n3 を-θだけ回転し、x軸に関して対称に折り返し、 >+θだけ回転したものが n1 です。したがって、θ回転行列を R(θ), x軸に関する折り返し >行列を X とすると をよみ、以下の式でa1X+b1Yを求めました。 double angSJ, angSK,angSI; //SJ,SKの角度 angSJ = Math.Atan2(-a2, b2); angSK = Math.Atan2(-a3, b3); //教えて頂いた方法からSIの角度を求める(少し違うかも) angSI = (angSK - angSJ+angSK); double a1, b1; a1 = Math.Cos(angSI) *-1; b1 = Math.Sin(angSI);     ↑これでどうでしょうか? CADで書いてみるとあっているように思えるのですが・・・

関連するQ&A