HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0821
rRRr頂点を図形(エンティティ)の中心を支点として回転させたい5解決


rRRr

リンク

2020/8/21(Fri) 07:24:21|NO.91216


; 頂点座標 vertices_x = -30, 30, 30, -30 vertices_y = 30, 30, -30, -30 ; エンティティ座標 entity_x = 200 entity_y = 100 ; 角度(°) degree = 0.0 *main radian = deg2rad(degree) redraw 0 color 0, 0, 0 boxf color 0, 255, 0 repeat ( length(vertices_x) | length(vertices_y) ) ; X vertex = vertices_x(cnt) x = ( entity_x + vertex ) x += (( cos(0) * cos(radian) - sin(0) * sin(radian) ) * absf(vertex) ) ; Y vertex = vertices_y(cnt) y = ( entity_y + vertex ) y += (( sin(0) * cos(radian) + cos(0) * sin(radian) ) * absf(vertex) ) ; 頂点描画 circle ( x - 5 ), ( y - 5 ), ( x + 5 ), ( y + 5 ), 1 loop ; 中心 color 255, 0, 0 circle ( entity_x - 5 ), ( entity_y - 5 ), ( entity_x + 5 ), ( entity_y + 5 ) redraw 1 ; 回転 degree += 2.5 degree \= 360 await 16 goto *main

エンティティの中心を支点で頂点を回転させるスクリプトを作っています。
上記のスクリプトでは加法定理を使って回転を行っていますが、
上手く動作しませんでした。どこが間違っているのか と 解決策 を教えてほしいです。
よろしくお願いします。



この記事に返信する


沢渡

リンク

2020/8/21(Fri) 08:36:13|NO.91217

加法定理を使わずに、最初に中心点からの長さと角度を求め、1フレームごとに角度を加算してゆく
方法にしてみましたが、これでは不味いでしょうか?

; 頂点座標 vertices_x = -30, 30, 30, -30 vertices_y = 30, 30, -30, -30 ddim vertices_r,length(vertices_x) //中心点からの長さ ddim vertices_rad,length(vertices_x) //中心点からの角度(ラジアン) repeat length(vertices_r) vertices_r(cnt)= sqrt(vertices_x(cnt)*vertices_x(cnt)+vertices_y(cnt)*vertices_y(cnt)) vertices_rad(cnt)=atan(vertices_y(cnt),vertices_x(cnt)) loop ; エンティティ座標 entity_x = 200 entity_y = 100 *main redraw 0 color 0, 0, 0 boxf color 0, 255, 0 repeat length(vertices_x) ; X x=int(cos(vertices_rad(cnt))*vertices_r(cnt)+entity_x) ; Y y=int(sin(vertices_rad(cnt))*vertices_r(cnt)+entity_y) ; 頂点描画 circle ( x - 5 ), ( y - 5 ), ( x + 5 ), ( y + 5 ), 1 loop ; 中心 color 255, 0, 0 circle ( entity_x - 5 ), ( entity_y - 5 ), ( entity_x + 5 ), ( entity_y + 5 ) redraw 1 ; 回転 repeat length(vertices_x) vertices_rad(cnt) += deg2rad(2.5) vertices_rad(cnt) \= 2.0*M_PI loop await 16 goto *main



あらや

リンク

2020/8/21(Fri) 13:10:03|NO.91221

加法定理でやるのならcos(0)やsin(0)ではなく
ループ開始前の時点で「中心から見た各頂点の角度」を求めないといけません。

この角度はソースを見る限りXとYの絶対値が同じなので
それぞれ45度、135度、225度、315度になります。


そして加法定理で求めたcos値、sin値に
中心座標と頂点の距離(つまり半径)を掛けて
エンティティ座標に合わせて平行移動します。

簡単に式を書くと
 A = 最初の角度(45度、135度、225度、315度)
 B = 加算する角度
 r = 半径
 c = 中心座標(エンティティ座標)

X座標 = cos(A+B) * r + c
Y座標 = sin(A+B) * r + c

こんな感じになります。


これらを踏まえた上でソースにすると

; 頂点座標 vertices_x = -30, 30, 30, -30 vertices_y = 30, 30, -30, -30 ; エンティティ座標 entity_x = 200 entity_y = 100 ; 角度(°) degree = 0.0 // 半径(中心から頂点までの距離) r = sqrt(30 * 30 + 30 * 30); // 中心から見た各頂点の角度 angles = atan( vertices_y(0), vertices_x(0) ), atan( vertices_y(1), vertices_x(1) ), atan( vertices_y(2), vertices_x(2) ), atan( vertices_y(3), vertices_x(3) ); *main radian = deg2rad(degree) redraw 0 color 0, 0, 0 boxf color 0, 255, 0 repeat ( length(vertices_x) | length(vertices_y) ) ; X ;vertex = vertices_x(cnt) ;x = ( entity_x + vertex ) ;x += (( cos(0) * cos(radian) - sin(0) * sin(radian) ) * absf(vertex) ) x = ( cos(angles(cnt)) * cos(radian) - sin(angles(cnt)) * sin(radian) ) * r + entity_x ; Y ;vertex = vertices_y(cnt) ;y = ( entity_y + vertex ) ;y += (( sin(0) * cos(radian) + cos(0) * sin(radian) ) * absf(vertex) ) y = ( sin(angles(cnt)) * cos(radian) + cos(angles(cnt)) * sin(radian) ) * r + entity_y ; 頂点描画 circle ( x - 5 ), ( y - 5 ), ( x + 5 ), ( y + 5 ), 1 loop ; 中心 color 255, 0, 0 circle ( entity_x - 5 ), ( entity_y - 5 ), ( entity_x + 5 ), ( entity_y + 5 ) redraw 1 ; 回転 degree += 2.5 degree \= 360 await 16 goto *main
こうなります。



rRRr

リンク

2020/8/21(Fri) 15:26:32|NO.91224

>加法定理を使わずに、最初に中心点からの長さと角度を求め、1フレームごとに角度を加算してゆく
>方法にしてみましたが、これでは不味いでしょうか?
問題ないです。加法定理を使わなくてもいけるのですね。

> ループ開始前の時点で「中心から見た各頂点の角度」を求めないといけません。
初期情報を与えなければならないのですか。勉強になりました。

沢渡さん あらやさん のコードを確認したところ私の望みどおりの動作をしてくれました。
ありがとうございました。



h

リンク

2020/8/21(Fri) 17:13:41|NO.91226

単純にラジアン値の足し算でできるのに加法定理とか持ち出すと複雑になる
学校で習うことってあんまり役に立たない
真に価値あるプログラミング技術は別のところにあると思う



rRRr

リンク

2020/8/21(Fri) 22:29:57|NO.91235

> 学校で習うことってあんまり役に立たない
ですねw



ONION software Copyright 1997-2023(c) All rights reserved.