|
|
2006/11/30(Thu) 18:22:04|NO.3874
現在、骨組みを移動させて多角形を変形するプログラムを作っているのですが、変形する部分のアルゴリズムが思いつかずお手上げ状態です。
どのような感じに組めばよろしいでしょうか?
お願いします。
dim point,2,10
point(0,0)=100,100
point(0,1)=100,140
point(0,2)=100,180
point(0,3)=100,220
point(0,4)=100,260
point(0,5)=150,260
point(0,6)=150,220
point(0,7)=150,180
point(0,8)=150,140
point(0,9)=150,100
dim bone,3,3
bone(0,0)=125,250,-1
bone(0,1)=125,180,0
bone(0,2)=0,0,1
//半径
r=4
repeat
bone(0,2)=mousex,mousey,1
redraw 0
//白に
color 255,255,255 : boxf
//各頂点描画
color
//多角形の頂点,辺描画
repeat length2(point)
circle point(0,cnt)-r,point(1,cnt)-r,point(0,cnt)+r+1,point(1,cnt)+r+1,1
if cnt!=0 {
line point(0,cnt-1),point(1,cnt-1),point(0,cnt),point(1,cnt)
}else{
line point(0,0),point(1,0),point(0,length2(point)-1),point(1,length2(point)-1)
}
loop
//変形する骨組みの描画
repeat length2(bone)
circle bone(0,cnt)-r,bone(1,cnt)-r,bone(0,cnt)+r+1,bone(1,cnt)+r+1,0
if bone(2,cnt)!=-1 : line bone(0,cnt),bone(1,cnt),bone(0,bone(2,cnt)),bone(1,bone(2,cnt))
loop
redraw 1
await 50
loop
|
|
2006/12/6(Wed) 19:57:52|NO.4000
こんなかんじですか?(^_^)b
dim point,2,10
point(0,0)=100,100
point(0,1)=120,140
point(0,2)=100,180
point(0,3)=100,220
point(0,4)=100,260
point(0,5)=150,260
point(0,6)=150,220
point(0,7)=150,180
point(0,8)=150,140
point(0,9)=150,100
dim bone,3,3
bone(0,0)=125,250,-1
bone(0,1)=125,180,0
bone(0,2)=0,0,1
//半径
r=4
repeat
bone(0,2)=mousex,mousey,1
redraw 0
//白に
color 255,255,255 : boxf
//各頂点描画
color
//多角形の頂点,辺描画
repeat length2(point)
getkey key,1
if key=0{
//ドラッグされていない
drag=0
}
//マウス選択
if (point(0,cnt)-r<=mousex)&(point(1,cnt)-r<=mousey)&(point(0,cnt)+r+1>=mousex)&(point(1,cnt)+r+1>=mousey){
if key=1:drag=1:oldcnt=cnt
}
if (drag=1)&(oldcnt=cnt){
//ドラッグされている
point(0,cnt)=mousex
point(1,cnt)=mousey
}
//描画
circle point(0,cnt)-r,point(1,cnt)-r,point(0,cnt)+r+1,point(1,cnt)+r+1,1
if cnt!=0 {
line point(0,cnt-1),point(1,cnt-1),point(0,cnt),point(1,cnt)
}else{
line point(0,0),point(1,0),point(0,length2(point)-1),point(1,length2(point)-1)
}
loop
//変形する骨組みの描画
//repeat length2(bone)
//circle bone(0,cnt)-r,bone(1,cnt)-r,bone(0,cnt)+r+1,bone(1,cnt)+r+1,0
//if bone(2,cnt)!=-1 : line bone(0,cnt),bone(1,cnt),bone(0,bone(2,cnt)),bone(1,bone(2,cnt))
//loop
redraw 1
await 50
loop
| |
|
2006/12/8(Fri) 16:47:18|NO.4051
返信ありがとうございます。
申し訳ありませんが、僕の考えているものと違いました。
3Dのワンスキンボーンみたいに骨を動かす事で外の図形を変形させるようなものです。
自分では一番近い関節と同じ角度で回転させればいいと思いましたが、曲げた内側が交差してしまいました。
お願いします。
|
|
2006/12/8(Fri) 20:05:07|NO.4053
かなり長くなってしまいましたが、
このBBSは添付ファイルがつけられないようなので直接貼り付けます・・・。
ボーンの変形を、近くの頂点の変形に反映させるのはその通りですが、
一番近い頂点だけではあるところに境目が出来てうまく出来ないはずです。
多角形上の点が受ける変形は、ボーン上の全ての点の移動に重み(影響力)を掛け合わせたものの総和になります。
多角形上の点とボーン上の点の距離が遠くなるほど影響力が低くなります。
本当は積分しなきゃいけないんですが、私の頭では解けませんでしたorz
遅くなりますがボーンを細かい点に分割して実際に総和を求めることででやってみました。
; ボーン数
boneCount = 3
; 移動前ボーン情報、X,Y,角度
ddim bone, 3, boneCount
repeat boneCount
bone(0,cnt) = 100.0+200.0*cnt, 100.0, 0.0
loop
; 移動後ボーン情報、X,Y,角度
ddim newBone, 3, boneCount
repeat boneCount
newBone(0,cnt) = bone(0,cnt), bone(1,cnt), 0.0
loop
; 頂点数
pointCount = 4
; 移動前頂点座標
ddim point, 2, pointCount
point(0,0) = 120.0, 80.0
point(0,1) = 480.0, 80.0
point(0,2) = 480.0, 120.0
point(0,3) = 120.0, 120.0
*l_Main
await 30
redraw 0
color 255, 255, 255
boxf
; 移動前ボーンを描画
color 0, 0, 0
repeat boneCount-1
line bone( 0, cnt+1 ), bone( 1, cnt+1 ), bone( 0, cnt ), bone( 1, cnt )
circle bone( 0, cnt )-2, bone( 1, cnt )-2, bone( 0, cnt )+3, bone( 1, cnt )+3, 0
loop
; ボーンを変形
newBone(0,0) = double(mousex), double(mousey)
newBone(2,0) = atan( newBone(1,1)-newBone(1,0), newBone(0,1)-newBone(0,0) )
newBone(2,1) = newBone(2,0)/2
; 移動後ボーンを描画
color 255, 0, 0
repeat boneCount-1
line newBone( 0, cnt+1 ), newBone( 1, cnt+1 ), newBone( 0, cnt ), newBone( 1, cnt )
circle newBone( 0, cnt )-2, newBone( 1, cnt )-2, newBone( 0, cnt )+3, newBone( 1, cnt )+3, 0
loop
; 多角形を構成する全ての線について
color 0, 0, 0
repeat pointCount
ncnt = (cnt+1)\pointCount
line point( 0, ncnt ), point( 1, ncnt ), point( 0, cnt ), point( 1, cnt )
circle point( 0, cnt )-2, point( 1, cnt )-2, point( 0, cnt )+3, point( 1, cnt )+3, 0
loop
; 最初の頂点(line で戻ってくるために記憶しておく)
isFirstPoint = 1
firstX = 0
firstY = 0
; 多角形の全ての線分について
repeat pointCount
p = cnt
np = (p+1)\pointCount
divPoint = 20
divBone = 10
; 線分を divPoint 個に分割して
repeat divPoint
s = double(cnt)/divPoint
; 多角形上の点
Xp = point( 0, p ) + ( point( 0, np ) - point( 0, p ) )*s
Yp = point( 1, p ) + ( point( 1, np ) - point( 1, p ) )*s
; (移動量*重み)の和
tmXp = 0.0
tmYp = 0.0
; 重みの和
tw = 0.0
; ボーンの全ての線分について
repeat boneCount-1
; 変形前ボーンの始点
X1 = bone(0,cnt)
Y1 = bone(1,cnt)
A1 = bone(2,cnt)
; 変形前ボーンの終点
X2 = bone(0,cnt+1)
Y2 = bone(1,cnt+1)
A2 = bone(2,cnt+1)
; 変形後ボーンの始点
X1_ = newBone(0,cnt)
Y1_ = newBone(1,cnt)
A1_ = newBone(2,cnt)
; 変形後ボーンの終点
X2_ = newBone(0,cnt+1)
Y2_ = newBone(1,cnt+1)
A2_ = newBone(2,cnt+1)
; divBone 個に分割して
repeat divBone+1
; 媒介変数 t: 0->1
t = double(cnt)/divBone
; 変形前ボーン上の点
Xt = X1+(X2-X1)*t
Yt = Y1+(Y2-Y1)*t
At = A1+(A2-A1)*t
; 変形後ボーン上の点
Xt_ = X1_+(X2_-X1_)*t
Yt_ = Y1_+(Y2_-Y1_)*t
At_ = A1_+(A2_-A1_)*t
; ボーン上の点の移動量
mXt = Xt_-Xt
mYt = Yt_-Yt
mAt = At_-At
; 変形前ボーン上の点から変形前多角形上の点までの距離
dXt = Xp-Xt
dYt = Yp-Yt
; 距離の二乗
dt2 = dXt*dXt+dYt*dYt
if dt2<0.01: dt2 = 0.01
; 移動の重み(=影響力、遠いほど小さい)
w = 1.0/dt2/dt2
; 変形後ボーン上の点の移動量*重み
mXpt = (dXt*cos(mAt)-dYt*sin(mAt)+Xt_-Xp)*w
mYpt = (dXt*sin(mAt)+dYt*cos(mAt)+Yt_-Yp)*w
; 蓄積していく
tmXp += mXpt
tmYp += mYpt
tw += w
loop
loop
; 変形後の多角形上の点
Xp_ = Xp + tmXp/tw
Yp_ = Yp + tmYp/tw
color 255, 0, 0
if isFirstPoint {
isFirstPoint = 0
firstX = Xp_
firstY = Yp_
pos Xp_, Yp_
} else {
line Xp_, Yp_
}
loop
loop
line firstX, firstY
redraw 1
goto *l_Main
| |
|
2006/12/9(Sat) 15:10:54|NO.4061
Asさん、Yukiさんありがとうございます。
まさにこの通りの事がやりたかったです。
難しそうですがじっくり考えてどうやっているか調べて見ます。
|
|
2006/12/9(Sat) 15:11:27|NO.4062
解決のチェックを付け忘れました
|
|