座標A(x1,y1,z1)から座標B(x2,y2,z2)への線分ABと
座標C(x3,y3,z3)から座標B(x4,y4,z4)への線分CDがあり、
線分ABと線分CDが交点を持つかどうかのプログラムを作りたいです。

C言語かVBかFortranで記述され、DirectXやOpenGLのライブラリを使わない方法の
サンプルソースの載っているページを教えていただけませんか?
また、ご迷惑でなければソースコードを記述していただけると助かります。

このQ&Aに関連する最新のQ&A

A 回答 (6件)

2線分の最短距離を求めてそれが0になる場合,交わっていると判断するのが良いと思います.


piyoは2線分の最短距離を求めるサブルーチンです.
2線分が平行なときは別の処理が必要ですね.

subroutine piyo(r1,r2,r3,r4,d)
implicit none
real(8),intent(in)::r1(3),r2(3),r3(3),r4(3)
real(8),intent(out)::d
real(8) r12(3),r34(3),b(2),a(2,2),s,t,rr(3),deta
r12(:)=r2(:)-r1(:)
r34(:)=r4(:)-r3(:)

!!! 2つの直線の距離の2乗をdとする
!!! d=|((r1+s*r12)-(r3+t*r34))|^2
!!! dの最小値を求める
!!! dをsについて偏微分
!!! r12・((r1+s*r12)-(r3+t*r34))=0
!!! dをtについて偏微分
!!! -r34・((r1+s*r12)-(r3+t*r34))=0
!!! sとtについてまとめると
!!! r12・r12 s - r12・r34 t = -r12・r1 +r12・r3
!!! -r34・r12 s + r34・r34 t = r34・r1 -r34・r3
a(1,1)=dot_product(r12,r12)
a(2,1)=-dot_product(r12,r34)
a(1,2)=a(2,1)
a(2,2)=dot_product(r34,r34)
b(1)=-dot_product(r12,r1)+dot_product(r12,r3)
b(2)=dot_product(r34,r1)-dot_product(r34,r3)
deta=a(1,1)*a(2,2)-a(1,2)*a(2,1)
!!! sとtについて解く
if(deta /=0.d0) then
s=(a(2,2)*b(1)-a(1,2)*b(2))/deta
t=(-a(2,1)*b(1)+a(1,1)*b(2))/deta
!!! elseif
!!! deta=0の場合は別途処理する必要あり.2つの線分が平行な場合deta=0となる.
end if

!!! この時点で0<s<1, 0<t<1でなければ,交わっていないことが分かる.
!!! if(s<0.d0.or.1.d0<s.or.t<0.d0.or.1.d0<t) then
!!! write(*,*) "交わってない"
!!! stop

if(s<0.d0) then
s=0.d0
elseif(1.d0<s)then
s=1.d0
end if
if(t<0.d0) then
t=0.d0
elseif(1.d0<t)then
t=1.d0
end if

!!! 最短距離の計算
rr(:)=r1(:)+s*r12(:)-(r3(:)+t*r34(:))
d=sqrt(dot_product(rr,rr))
end subroutine piyo

program hoge
implicit none
real(8) r1(3),r2(3),r3(3),r4(3),d
r1(:)=(/0.d0,0.d0,0.d0/)
r2(:)=(/1.d0,1.d0,1.d0/)
r3(:)=(/1.d0,0.d0,0.d0/)
r4(:)=(/1.d0,1.d0,0.d0/)
call piyo(r1,r2,r3,r4,d)
if(d<1.d-15) then
write(*,*) "交わる"
endif
end program

この回答への補足

質問者のGyustabです。

以下3点質問させてください。

(1)!!! 2つの直線の距離の2乗をdとする
 !!! d=|((r1+s*r12)-(r3+t*r34))|^2
 !!! dの最小値を求める
 の部分について 

 線分r1r2上の点を(r1+s*r12)
 線分r3r4上の点を(r3+t*r34) とすると
 
 2点間の距離は
 sqrt( ( (r3+t*r34)-(r1+s*r12) )^2 ) ⇒ (r3+t*r34)-(r1+s*r12) となり

 距離の2乗は ((r3+t*r34)-(r1+s*r12))^2 となるという理解で良いでしょうか?

(2)距離の2乗をdとしているのは、
 s,tについて微分出来る形にするためわざと2乗していると考えれば良いですか?

(3) a(1,1)=dot_product(r12,r12)
  a(2,1)=-dot_product(r12,r34)
  a(1,2)=a(2,1)
  a(2,2)=dot_product(r34,r34)
  b(1)=-dot_product(r12,r1)+dot_product(r12,r3)
  b(2)=dot_product(r34,r1)-dot_product(r34,r3)
  deta=a(1,1)*a(2,2)-a(1,2)*a(2,1)
  
  上記数式がわかりません、
  一連の流れは内積を使って何を計算しているのでしょうか?

補足日時:2011/04/21 10:15
    • good
    • 0
この回答へのお礼

わざわざFortranのプログラムを記述いただきありがとうございます。

本日、線分が半径を持つことが判明したため、
線分が衝突しないためには、
線分間で 半径*2 より大きい離隔距離が必要になりました
そのため nineexitさんのコードを解析し、理解したく思います。

まず、
!!! 2つの直線の距離の2乗をdとする
!!! d=|((r1+s*r12)-(r3+t*r34))|^2
の部分がわからず、なぜこのように定義できるのか現在ネットで調査しています。

dot_product はFortranの関数でベクトル間の内積を求めるということがわかりました、
以下のページを参考にエクセルVBAのコードに落とせるよう調べています。
http://homepage1.nifty.com/gfk/vector-naiseki.htm

まだまだ時間がかかりますが少しづつコードを解析していきます。

お礼日時:2011/04/20 20:00

> つまり、2直線間の距離の2乗であるdは、


> 2直線間の距離同士の内積と考えるということでしょうか?

2つの直線上にある"2つの点"の距離の自乗がdです.
「2直線間の距離同士の内積」ではありません.
内積は距離同士でとるものではなくベクトル同士でとるものです.
同じベクトル同士の内積を取ると長さの自乗が得られるので,内積を取っています.
    • good
    • 0
この回答へのお礼

>2つの直線上にある"2つの点"の距離の自乗がdです.
>「2直線間の距離同士の内積」ではありません。
>内積は距離同士でとるものではなくベクトル同士でとるものです。
>同じベクトル同士の内積を取ると長さの自乗が得られるので,内積を取っています.
ご指摘ありがとうございます、数学素人の回答ですいません、
ベクトルと距離がごちゃまぜになっていました、
ご指摘いただいた点および今まで教えていただいた点を
含めて一度ソースコードを納得できるところまでコーディングしてみます。

お礼日時:2011/04/25 22:48

回答に対する質問への回答です。



(1)
r1, r2, r3, r4, r12, r34はベクトルです。
ベクトルa=(a1,a2,a3)の長さの自乗はa同士の内積(a・a)になります。
サブルーチンの終わりに
rr(:)=r1(:)+s*r12(:)-(r3(:)+t*r34(:))
d=sqrt(dot_product(rr,rr))
とありますが、これが長さの自乗を計算しているところです。

(2)
微分しやすいように自乗しています。
2直線上の点の距離の最小値を求めるためには、2直線上の点の距離の自乗の最小値を求めればよいので、このようなことをしています。
最後に最短距離を算出するときは、きちんとルートを取っています。

(3)
!!! r12・r12 s - r12・r34 t = -r12・r1 +r12・r3
!!! -r34・r12 s + r34・r34 t = r34・r1 -r34・r3
を行列A、ベクトルbを用いて表記しました。
Ax=bの形でxはsとtからなるベクトルです。x=(s,t)
detaは行列A行列式です。
ただの連立一次方程式なので、行列やベクトルを持ち出す必要はありません。
    • good
    • 0
この回答へのお礼

返答ありがとうございます。

>ベクトルa=(a1,a2,a3)の長さの自乗はa同士の内積(a・a)になります。
つまり、2直線間の距離の2乗であるdは、
2直線間の距離同士の内積と考えるということでしょうか?


>d=sqrt(dot_product(rr,rr))
>とありますが、これが長さの自乗を計算しているところです。
ベクトルa=(a1,a2,a3)の長さの自乗はa同士の内積(a・a)ということなので、
dot_product(rr,rr)はベクトルrrの長さの2乗と同じ意味ですね、
ということはベクトルrr同士の内積の平方根を求めるとベクトルrrの長さが出てくるという事ですね



>微分しやすいように自乗しています。
>2直線上の点の距離の最小値を求めるためには、
>2直線上の点の距離の自乗の最小値を求めればよいので、このようなことをしています。
>最後に最短距離を算出するときは、きちんとルートを取っています。
とてもわかりやすかったです、
紙上に数式を記述し、展開してs,tに対して微分したところ、
sとtについてまとめた数式まで辿り着けました。

お礼日時:2011/04/21 19:50

#1です。



>下記4つの数式の条件を満たすのは4点の座標の値が整数の場合のみでしょうか?
>座標の値が単精度浮動小数点や倍精度浮動小数点の場合は有効桁数の範囲内であれば成立しますか?

数学的には、実数の範囲で成立します。

コンピュータで単精度、倍精度で計算する場合は当然有効桁数の問題がでてきます。
特に、減算で有効桁数が桁落ちする可能性がでてくるので、十分考慮する必要があります。


前回の回答で、最初に「コードを書くのは面倒」と書いたのはそういう意味です。悪しからず。
    • good
    • 0
この回答へのお礼

ご返答いただきありがとうございます。


>前回の回答で、最初に「コードを書くのは面倒」と書いたのはそういう意味です。
>悪しからず。
いえいえ、疑問に対する答えがわかっただけで助かりました。

明日、会社にて数式の許容誤差や
計算上の有効桁数の桁落ちをどのようにすれば良いかを熟考してみます。

お礼日時:2011/04/19 21:01

学校の宿題か何かの回答をここに丸投げ質問してないですか。

そういうのは先般の大学入試問題にでも批判を浴びたはず。
もしそうなら、授業で先生に教えてもらえるのではないですか。それをここで教えるのは授業妨害とも言える。
Googleででも「空間 2直線 交点座標 」などで照会すれば記事はある。
ベクトルや行列の知識が必要な記事が多いが。そういうのは理解できるのか。
http://www.teu.ac.jp/aqua/GS/text/PDF/3DMath.pdf
    • good
    • 0
この回答へのお礼

>学校の宿題か何かの回答をここに丸投げ質問してないですか。そういうのは先般の大学入試問題にでも>批判を浴びたはず。
>もしそうなら、授業で先生に教えてもらえるのではないですか。それをここで教えるのは授業妨害とも>言える。
いいえ違います社会人です、仕事上必要であったため質問しました、
教えてくれる先生などいませんし、授業を妨害している暇はありません。

>Googleででも「空間 2直線 交点座標 」などで照会すれば記事はある。
「線分 交点 3次元」、「直線 衝突判定 3次元」、「直線 交点 サンプルプログラム」等で
検索しましたが、概念はたくさんあっても私の解読できるC言語・VisualBasic・Fortran・javaのソースが発見できなかったためここに質問しました。
客先にはエクセルで提供するのでDirectXやOpenGLのようなライブラリを要するものは使用したくないのです。

>ベクトルや行列の知識が必要な記事が多いが。そういうのは理解できるのか。
数学者でも教師でも数値解析エンジニアでもないのでベクトルや行列について1~100まで
理解する気はありません、客先の仕様を満たすために必要な概念と考え方、
ソースコードへ落とす事が必要なだけです。

以上、なにか返答があればどうぞ

お礼日時:2011/04/19 13:25

コードを書くのは面倒なので考え方だけ。



x12=x2-x1、y12=y2-y1、z12=z2-z1、
x34=x4-x3、y34=y4-y3、z34=z4-z3とすると、
線分AB上の点は(x1+s*x12, y1+s*y12, z1+s*z12) (0≦s≦1)
線分CD上の点は(x3+t*x34, y3+t*y34, z3+t*z34) (0≦t≦1)
と表現できます。

線分ABと線分CDが交点を持つとすると、
(1) x1+s*x12=x3+t*x34
(2) y1+s*y12=y3+t*y34
(3) z1+s*z12=z3+t*z34
が成り立ちます。

(1),(2)式からs,tを求めると、
s=((x3-x1)*y34-x34*(y3-y1))/(x12*y34-x34*y12)
t=((x1-x3)*y12-x12*(y1-y3))/(x34*y12-x12*y34)

このS,tが0≦s≦1 , 0≦t≦1 の条件を満たし、かつ、
このs,tを(3)式に代入して等号が成立するときに交点を持ちます。

あとは、これをコードにすればいいだけです。


補足
x12*y34=x34*y12 の場合、2直線は、同じか、並行か、ねじれ位置にあるので交差していないことになります。

この回答への補足

質問者のGyustabです。

コーディング中疑問に思ったため再度質問させてください。

下記4つの数式の条件を満たすのは4点の座標の値が整数の場合のみでしょうか?
座標の値が単精度浮動小数点や倍精度浮動小数点の場合は有効桁数の範囲内であれば成立しますか?

成立しないのであれば (x12*y34)/(x34*y12)≒1.00000 のように限りなく1に近づく誤差を
計算したり、s=・・・・やt=・・・の式の乗算・除算の順番を考え有効桁数の
精度を考慮した計算をする必要があるのではないかと思っています。


数式1:s=((x3-x1)*y34-x34*(y3-y1))/(x12*y34-x34*y12)
数式2:t=((x1-x3)*y12-x12*(y1-y3))/(x34*y12-x12*y34)
数式3:z1+s*z12=z3+t*z34
数式4:x12*y34=x34*y12

補足日時:2011/04/19 19:24
    • good
    • 0
この回答へのお礼

返信ありがとうございます、以下の部分が大変助かりました。

s=((x3-x1)*y34-x34*(y3-y1))/(x12*y34-x34*y12)
t=((x1-x3)*y12-x12*(y1-y3))/(x34*y12-x12*y34)

さまざまなホームページで紹介されている概念の通りにやれば紙の上では解けるのですが、
どうやって2線分の交点をソースコードに落とせば良いかで四苦八苦しておりました。

今よりコーディングしてみます。
補足もありがとうございます、この部分も条件に組み込みます。

お礼日時:2011/04/19 13:31

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q直交する2直線

方程式2x^2-3xy+λy^2+5y+μ=0がxy平面上の直交する2直線を表すようにλ,μを定め、この2直線の方程式を求めよという問題なんですが、解き方、考え方が分かりません。
答は λ=μ=-2
  2x+y=2、2y-x=1 です。

直交する2直線が上方程式で表せれるということもよく分からないので、その辺りもよろしかったら教えてください。

Aベストアンサー

直線の式は ax+by+c=0 という風に表す、というのはOKですね。
与えられた式が(ax+by+c)(px+qy+r)=0 とできたとすると
ax+by+c=0 または px+qy+r=0 となり、2つの直線を表すことになります。
ここまでは、may-may-jpさんの回答の通りですが、ただ因数分解できるだけではλとμは特定できません。そこで必要になるのが「直交」の条件です。

直交する条件は2つの直線の傾きの積が-1になることです。
ax+by+c=0 を変形して y=(a/b)x+(c/b) ただし b≠0
同様に px+qy+c=0 を変形して y=(p/q)x+(r/q) ただし q≠0
とすると 傾きはそれぞれ a/b,p/qですか積が-1 すなわち
(a/b)・(p/q)=ap/bq = -1 ∴ ap = -bq が直交条件です。

なお、b=0(q=0)のときは直線はy軸に平行になります。このとき直交する直線はx軸と平行になり、xの係数が0 つまりp=0(a=0) になります。このときもap = -bq (=0)で成り立ちます。

さて(ax+by+c)(px+qy+r)=0 の左辺を展開すると
apx^2+bqy^2+(aq+bp)xy+(ar+cp)x+(br+cq)y+cr=0
となります。(途中の計算はご自分で確かめてください。)
ここで直交条件をみると x^2 とy^2の係数に注目すればよいことが分かります。
与式に戻って、2x^2-3xy+λy^2+5y+μ=0のx^2 とy^2の係数をみれば 2=-λ すなわちλ=-2が求められます。
これを代入して
2x^2-3xy+2y^2+5y+μ=0
これが(ax+by+c)(px+qy+r)=0 の形に因数分解できれば良いわけです。
x^2,y^2,xyの係数に注目すると
(2x+y+c)(x-2y+r)=0 --(*)という形になることは容易に分かります。
あとはx,yの係数から
2r+c=0
r-2c=5
の2式が出ますので、連立方程式を解いて
r=1, c=-2 よってμ=cr=-2
となります。
このrとcを(*)に代入すれば
(2x+y-2)(x-2y+1)=0 となり、直線の式は 2x+y-2=0,x-2y+1=0
と求まります。
答えの2x+y=2、2y-x=1 は上記の式の定数項を移行した形ですね。

直線の式は ax+by+c=0 という風に表す、というのはOKですね。
与えられた式が(ax+by+c)(px+qy+r)=0 とできたとすると
ax+by+c=0 または px+qy+r=0 となり、2つの直線を表すことになります。
ここまでは、may-may-jpさんの回答の通りですが、ただ因数分解できるだけではλとμは特定できません。そこで必要になるのが「直交」の条件です。

直交する条件は2つの直線の傾きの積が-1になることです。
ax+by+c=0 を変形して y=(a/b)x+(c/b) ただし b≠0
同様に px+qy+c=0 を変形して y=(p/q)x+(r/q) ただし...続きを読む

Q座標A(X,Y)の線分(aX,aY)(bX,bY)に対称な座標の求め方

VBで図形を入力した線分に対称に反転した図形と書こうとしています。
その為に必要な座標A(X,Y)の線分(aX,aY)(bX,bY)に対称な
座標B(X',Y')の求め方についてご教授お願いいたします。

Aベストアンサー

 次の関係から連立方程式を解いてください。

 点P(aX,aY)、点Q(bX,bY)とすると、

・直線PQと直線ABは垂直に交わる。 ⇒2つの直線の傾きを掛けると-1になる。

・2点ABの中点Mが直線PQ上を通る。⇒直線PQの方程式に点M((X+X')/2, (Y+Y')/2)を代入する。

Qxy平面において、原点Oを通り互いに直交する2直線

xy平面において、原点Oを通り互いに直交する2直線を引き、直線x=-1および直線x=3√3 との交点をそれぞれP、Qとする。 OP+OQの最小値を求めよ。

Aベストアンサー

原点Oを通り互いに直交する2直線をm,nとしましょうか。交点は4つある。
A: mとx=-1との交点
B: mとx=3√3との交点
C: nとx=-1との交点
D: nとx=3√3との交点
P, Qってどれだよ?というのがソモソモの疑問デスヨネ?
(1) OP+OQがOA+OBのことなのだとすると(直線nには出番がありませんが)、OA+OBの最小値が1+3√3であることは自明。
(2) OP+OQがOC+ODでも同じです。(直線mには出番がありませんで)最小値は1+3√3。
(3) OP+OQがOA+OCのことなのだとすると(直線x=3√3には出番がありませんで)、△OACは直角三角形である。明らかに、直角二等辺三角形の場合にOA+OCが最小になるんで、2√2が答。
(4) OP+OQがOB+OCのことだったら(直線x=-1には出番がありませんで)、(3)と比べて、直角三角形の各辺の長さが3√3倍になるだけなので、(2√2)×(3√3)が答である。
 残る問題は、
(5) OP+OQがOA+ODであるとき。(ま、出題者の意図は専らこれなんでしょうけど、はっきり書いてないと(1)~(4)も省けません。)
 交差する相手の直線を x=-1とx=3√3じゃなくて一般にx=a, x=b (a≠0, b≠0)だとしてみましょう。
 そして、mの方程式を ux + vy = 0 とすると、v=0の場合にはmはx=aともx=bとも交点を持たない。また、u=0の場合にはnがaともx=bとも交点を持たない。だから(5)においては、これらの場合は除外してよろしい。というわけで、mの方程式を
   y = αx (α≠0)
と書いても差し支えない。このときnの方程式は
  y = x/α
です。
  A= (a, aα)
  D= (b, b/α)
であり、原点からの距離は
  OA = |A| = |a|√(1+α^2)
  OD = |D| = |b|√(1+1/(α^2))
である。
OA+OD をfと書くことにすると、
  f = |A|+|D| = |a|√(1+α^2) + |b|√(1+1/(α^2))
である。ここで
  z = α^2
とおくと zは正の実数 (z>0)です。zを使って
  f = |a|√(1+z) +|b|√(1+1/z)
と書き直します。さて、fの極小値を計算する。つまり方程式
  df/dz = 0
を満たすzを計算するわけで、df/dzを計算して方程式に代入すると
  |a|/(2√(1+z)) - |b|/(z^2)/(2√(1+1/z)) = 0
移項して分母を払うと
  |a|(z^2)√(1+1/z) = |b|√(1+z)
両辺を2乗して
  (a^2)(z^4)(1+1/z) = (b^2)(z+1)
つまり
  (a^2)(z^3)(z+1) = (b^2)(z+1)
z>0なので(z+1)で割って
  (a^2)(z^3) = (b^2)
a≠0なので
  z^3 = (b/a)^2
である。ただし、zは正の実数でなくてはならないのでした。
 ところで、aとbは0でない実数でした。なので、a,bを決めるとこの方程式を満たすzはいつも丁度ひとつ存在して、それは
z = ((b/a)^2)の立方根
です。これを
  f = |a|√(1+z) +|b|√(1+1/z)
に代入するとfの極値、つまりfの極小値あるいはfの極大値が得られる。
 ですが、fの極値を与えるzがただ一つしかなくて、しかもz→0やz→+∞のときにfが+∞に発散するんですから、極大なんてそもそも存在しないのは明らか。なので、この計算でfの極小値が得られ、これがfの最小値でもある。

原点Oを通り互いに直交する2直線をm,nとしましょうか。交点は4つある。
A: mとx=-1との交点
B: mとx=3√3との交点
C: nとx=-1との交点
D: nとx=3√3との交点
P, Qってどれだよ?というのがソモソモの疑問デスヨネ?
(1) OP+OQがOA+OBのことなのだとすると(直線nには出番がありませんが)、OA+OBの最小値が1+3√3であることは自明。
(2) OP+OQがOC+ODでも同じです。(直線mには出番がありませんで)最小値は1+3√3。
(3) OP+OQがOA+OCのことなのだとすると(直線x=3√3には出番がありませんで)、△OACは直角三角形であ...続きを読む

Q2つの座標と角度から交点座標の求め方

(X1, Y1)と(X2, Y2)の2点の座標と角度θがあります。
この情報から交点座標(XX, YY)を求めたいと思っています。

どのような計算式になるのでしょうか?

VB6にて作成しております。
よろしくお願いします。

Aベストアンサー

Windowsで閉図形の内外の点の判定をしたのであれば
WinAPIで使われるのRegionを使ってみるのも一つの方法ですよ

CreatePolygonRgn,PtInRegion,CloseHandleの3つのAPI関数とPOINTAPI構造体を定義すれば使えます

dim pts(20) as POINTAPI
' ptsの配列に各頂点の座標を設定
dim hRng as Long
' 15の頂点の場合は 2番目の引数の20を 15に変更
' 3番目は定数なので APIビューアで探してください
' 設定できる値は ALTERNATE=1、WINDING=2 です
hRng = CreatePolygonrng( pts(0), 20, WINDING )
if hRng<> 0 then
  if PtInRegion( hRng, x, y ) then
    ' ここに来れば内部
  else
    ' ここに来れば外部
  end if
end if
CloseHandle hRng

といった具合です
API宣言は VB6付属の APIビューアで定義を探してみてください

# 関連質問があるならそれも明記したほうがいいように思います
# http://oshiete1.goo.ne.jp/qa5330333.html

Windowsで閉図形の内外の点の判定をしたのであれば
WinAPIで使われるのRegionを使ってみるのも一つの方法ですよ

CreatePolygonRgn,PtInRegion,CloseHandleの3つのAPI関数とPOINTAPI構造体を定義すれば使えます

dim pts(20) as POINTAPI
' ptsの配列に各頂点の座標を設定
dim hRng as Long
' 15の頂点の場合は 2番目の引数の20を 15に変更
' 3番目は定数なので APIビューアで探してください
' 設定できる値は ALTERNATE=1、WINDING=2 です
hRng = CreatePolygonrng( pts(0), 20, WINDING )
if hRng<>...続きを読む

Q2直線が直交するように、A,Bと交点の途中式を教えてください

2直線が直交するように、A,Bと交点の途中式を教えてください

(1) (x-3)/2 = (y+1)/-3 = (z-4)/A , (x+5)/3 = (y+6)/4 = z+B
A.A=6 B=4 交点(1,2,2)

(2) x+3 = (y-1)/2 = (z-7)/A , x/2 = (y-B)/5 = (z+2)/4
A.A=-3 B=7 交点(0,7,-2)

全く分かりません。例が参考にならないのでよろしくお願いします

Aベストアンサー

(1)
(x-3)/2 = (y+1)/-3 = (z-4)/A
の方向ベクトルは(2,-3,A)

(x+5)/3 = (y+6)/4 = (z+B)/1
の方向ベクトルは(3,4,1)
2つの方向ベクトルが直交するから内積=0
(2,-3,A)・(3,4,1)=6-12+A=0 ∴A=6

この時前半の直線は
(x-3)/2 = (y+1)/-3 = (z-4)/6(=kとおく)
媒介変数表現で
x=2k+3,y=-3k-1,z=6k+4…(1)

後半の直線は
(x+5)/3 = (y+6)/4 = (z+B)/1=h
とおけば媒介変数表現で
x=3h-5,y=4h-6,z=h-B…(2)

(1),(2)を連立方程式として解けば交点の座標(x,y,z)とBが求まります。
x=1,y=2,z=-2,B=4,k=-1,h=2
答えのA=6,B=4は合っていますが、交点の座標が正しくないようです。
正しい交点は(1,2,-2)です。
確認してみて下さい(元の直線の方程式に代入して式が成り立つかで分かります)。

(2)も同様の方法で出来ますのでやってみて下さい。

(1)
(x-3)/2 = (y+1)/-3 = (z-4)/A
の方向ベクトルは(2,-3,A)

(x+5)/3 = (y+6)/4 = (z+B)/1
の方向ベクトルは(3,4,1)
2つの方向ベクトルが直交するから内積=0
(2,-3,A)・(3,4,1)=6-12+A=0 ∴A=6

この時前半の直線は
(x-3)/2 = (y+1)/-3 = (z-4)/6(=kとおく)
媒介変数表現で
x=2k+3,y=-3k-1,z=6k+4…(1)

後半の直線は
(x+5)/3 = (y+6)/4 = (z+B)/1=h
とおけば媒介変数表現で
x=3h-5,y=4h-6,z=h-B…(2)

(1),(2)を連立方程式として解けば交点の座標(x,y,z)とBが求まります。
x=1,y=2,z=-2,B=4,k=-1,h=2
答えの...続きを読む

QExcel VBAでグラフ作成。A,C列をx値, B,D列をy値にした複数プロット

ExcelのVBAでグラフをChartType = xlXYScatterLinesでグラフを作っています。仮に各列10行でAからF列までデータがあるとします。
Set chartObj = ActiveSheet.ChartObjects.Add(170, 170, 280, 170)
With chartObj.Chart
.ChartType = xlXYScatterLines
.SetSourceData Worksheets(1).Range("A1:F10"), _
PlotBy:=xlColumns
.HasLegend = False
End With

上記のようにしてしまうと、x値がA1:A10で、y値がB1:B10,C1:C10・・・・のプロットが5本作成されてしまいます。

以下のようにするにはどうすればよろしいでしょうか。
第一のプロットはx値をA1:A10, y値をB1:B10としてグラフを作成します。次にこのグラフにx値をC1:C10, y値をD1:D10とした第二のプロットを追加、同様に第三はx値をE1:E10, y値をF1:F10としてプロットを追加したグラフを作成したいのですが、このようなグラフはVBAで作成可能でしょうか。

本番のグラフは行数と列数はいろいろな場合があるので、行数と列数のパラメータに任意の値を代入し、Forループで様々な形態に対応できるものを作りたいと考えています。

ExcelのVBAでグラフをChartType = xlXYScatterLinesでグラフを作っています。仮に各列10行でAからF列までデータがあるとします。
Set chartObj = ActiveSheet.ChartObjects.Add(170, 170, 280, 170)
With chartObj.Chart
.ChartType = xlXYScatterLines
.SetSourceData Worksheets(1).Range("A1:F10"), _
PlotBy:=xlColumns
.HasLegend = False
End With

上記のようにしてしまうと、x値がA1:A10で、y値がB1:B10,C1:C10・・・・のプロットが5本作成されてしまいます。

以下のようにするにはどうすれ...続きを読む

Aベストアンサー

Dim chartObj As ChartObject
Dim r As Range
Dim i As Long

Set chartObj = ActiveSheet.ChartObjects.Add(170, 170, 280, 170)
Set r = Worksheets(1).Range("A1:F10")
With chartObj.Chart
  .ChartType = xlXYScatterLines
  .HasLegend = False
  For i = 1 To 5 Step 2
    With .SeriesCollection.NewSeries
      .XValues = r.Columns(i)
      .Values = r.Columns(i + 1)
    End With
  Next
End With

Set r = Nothing
Set chartObj = Nothing

...こんな感じ。
普通に手作業で作成するものをマクロ記録すればヒントになるでしょう。
後から系列を追加すればいいわけです。

>本番のグラフは行数と列数はいろいろな場合があるので...
...に対応させる一例としては以下。

Const MN = 1 'データ開始行
Const MX = 10 'データ個数
Dim chartObj As ChartObject
Dim x, y
Dim z As Long
Dim i As Long

x = VBA.Array(1, 3, 5) 'x値の列
y = VBA.Array(2, 4, 6) 'y値の列
Set chartObj = ActiveSheet.ChartObjects.Add(170, 170, 280, 170)
With chartObj.Chart
  .ChartType = xlXYScatterLines
  .HasLegend = False
  For i = 0 To UBound(x)
    With .SeriesCollection.NewSeries
      .XValues = Cells(MN, x(i)).Resize(MX)
      .Values = Cells(MN, y(i)).Resize(MX)
    End With
  Next
End With

Set chartObj = Nothing

Dim chartObj As ChartObject
Dim r As Range
Dim i As Long

Set chartObj = ActiveSheet.ChartObjects.Add(170, 170, 280, 170)
Set r = Worksheets(1).Range("A1:F10")
With chartObj.Chart
  .ChartType = xlXYScatterLines
  .HasLegend = False
  For i = 1 To 5 Step 2
    With .SeriesCollection.NewSeries
      .XValues = r.Columns(i)
      .Values = r.Columns(i + 1)
    End With
  Next
End With

Set r = Nothing
Set chartObj = Nothing

.....続きを読む

QFortranで直交座標から極座標変換のプログラム

Fortranで直交座標から極座標変換のプログラム

FDTD法を用いて、散乱電場を求める際、最初Ex(i,j,k), Ey(i,j,k), Ez(i,j,k)を求めましたが、
それから座標をr方向に座標変換したく、プログラムを作ろうと思っているのですが、どのように書いてよいのか悩んでいます。
単位ベクトル r = (x,y,z)=(sinθcosφ,sinθsinφ,cosθ)と定義できるのですが、これを
どのように極座標のプログラムとして書いてよいのかわかりません。
どなたかわかる方がいらっしゃたら教えて下さい。よろしくお願いします。

Aベストアンサー

座標変換(デカルト座標から極座標)に伴う単位ベクトルの変換またはベクトル成分の変換を行おうということなら下記URL参照。

参考URL:http://www-d.ige.solan.chubu.ac.jp/goto/docs/math/pm6.ssi

Q「Cell( n , "A" )よりも10上のセルに1 or 2 が記入されていなければ、Cell( n , "A" )に1を記入する」

「Cell( n , "A" )よりも10上のセルに1 or 2 が記入されていなければ、Cell( n , "A" )に1を記入する」
というコードを作ってみましたが、メチャクチャな動きになってしまいます(動きが読めません)。
どこが間違っているのか教えてください。
また、もし、よりわかりやすいコードがありましたら教えていただけると嬉しいです。
よろしくお願いいたします。

Sub Cell( n , "A" )に1を記入する()

Dim n As Long
Dim m As Long
Dim s As Long

'現在のセル( n , "A" )より14行上に数値がないことを確認するために
'14行上のセルを全て足し算しています。
For m = n - 14 To n - 1
s = s + Worksheets("Sheet1").Cells(m, "A").Value
Next

'足し算結果がゼロならば何も記入していないと判断し、
'数字の「1」を記入します。
If s >= 1 Then
Worksheets("Sheet1").Cells(n - 1, "A").Value = 0
ElseIf s = 0 Then
Worksheets("Sheet1").Cells(n - 1, "A").Value = 1
End If
End Sub

「Cell( n , "A" )よりも10上のセルに1 or 2 が記入されていなければ、Cell( n , "A" )に1を記入する」
というコードを作ってみましたが、メチャクチャな動きになってしまいます(動きが読めません)。
どこが間違っているのか教えてください。
また、もし、よりわかりやすいコードがありましたら教えていただけると嬉しいです。
よろしくお願いいたします。

Sub Cell( n , "A" )に1を記入する()

Dim n As Long
Dim m As Long
Dim s As Long

'現...続きを読む

Aベストアンサー

はいはい了解。

今着目しているセルが (n,1)であるとする。

条件: 今いるところから上に14行サーチして、一度でも1か2の値が見つかったら
     回答を0とする。14行すべてに1・2の値がひとつも含まれていなければ1とする。



Ans = 1

for i = 1 to 14

x = cells ( n - i , 1 ).value

if x = 1 or x = 2
then
Ans = 0
endif
next i


cells ( n , 1 ) = Ans


デフォルトの回答値=1としておき、一回でも条件にヒットしたら回答値=0にする。
ヒットしたらfor~nextを強制的に閉じてもいいけど、面倒なのでそのまま14回検索する。

Q直線を描画するプログラム

初歩的ですみません。
マウスで始点と終点を決めて直線を書くプログラムを知っている方がおりましたら教えてください。

よろしくお願いします。

Aベストアンサー

WinTKというのは良く分からないんで、MFCの方を……
とりあえずダイアログアプリケーションで説明すると、

1.
 ダイアログベースのスケルトンを作ります
2.
 xxxDlg.h に座標を保持るためメンバを追加します。
class CxxxDlg : public CDialog
 {
   CPoint m_ptBegin, m_ptEnd;

3.
クラスウィザードで WM_LBUTTONUP, WM_RBUTTONUP を選択します。

4.
 void CxxxDlg::OnLButtonUp(UINT nFlags, CPoint point)
 {
   // ここの point に左ボタンが離された座標が入ってますので保持しておきます(始点)
   m_ptBegin = point;
   CDialog::OnLButtonUp(nFlags, point);
 }
5.
 void CxxxDlg::OnRButtonUp(UINT nFlags, CPoint point)
 {
   // ここの point に右ボタンが離された座標が入ってますので保持しておきます(終点)
   m_ptEnd = point;

   // 再描画します。
   InvalidateRect( NULL );

   CDialog::OnRButtonUp(nFlags, point);
 }

6.
 CxxxDlg::OnPaint()関数の以下の部分を変更します。

 else
 {
   CDialog::OnPaint();
 }
      ↓
 else
 {
   CPaintDC dc( this );

   dc.MoveTo( m_ptBegin );
   dc.LineTo( m_ptEnd );

   CDialog::OnPaint();
 }

と、大体こんな感じです。m_ptBegin, m_ptEndはコンストラクタで初期化してやっておいて
ください。説明が大雑把なんでわかりにくかったら言ってくださいね。

ほな。

WinTKというのは良く分からないんで、MFCの方を……
とりあえずダイアログアプリケーションで説明すると、

1.
 ダイアログベースのスケルトンを作ります
2.
 xxxDlg.h に座標を保持るためメンバを追加します。
class CxxxDlg : public CDialog
 {
   CPoint m_ptBegin, m_ptEnd;

3.
クラスウィザードで WM_LBUTTONUP, WM_RBUTTONUP を選択します。

4.
 void CxxxDlg::OnLButtonUp(UINT nFlags, CPoint point)
 {
   // ここの point に左ボタンが離された座標が入ってますので保...続きを読む

Q交差する2線分の交点座標の求め方

2つの線分が交差する場に交点の座標を求めようと思っています。
アドバイスを頂けないでしょうか?

入力値:(aX1, aY1)(aX2, aY2)
    (bX1, bY1)(bX2, bY2)
出力値:(X, Y)
よろしくお願いします。

Aベストアンサー

点(aX1, aY1)と点(aX2, aY2)を通る直線の方程式Aと、
点(bX1, bY1)と点(bX2, bY2)を通る直線の方程式Bを求める。
方程式Aと方程式Bを連立方程式として解き2つの直線の交点(X,Y)を求める。

ここまで、ただの数学問題ですね。

これで(X,Y)が入力の4つの点の座標で表現できたはずなので
そのままプログラムに書けばよいです。

質問文では直線ではなく線分の交点なので、
線分が交わらないことも検出したいならそのロジックも入れましょう。
(求めた交点(X,Y)が2つの線分上にあるかチェックする。)


人気Q&Aランキング

おすすめ情報