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


HSPTV!掲示板


未解決 解決 停止 削除要請

2023
0704
YUZRANIUMhgimg4で正n角柱4解決


YUZRANIUM

リンク

2023/7/4(Tue) 23:32:00|NO.99683

表題について、、、

簡単な立体(円柱とか)を生成する命令がなかったので、
「やってみよー」と思い、色々遊んでいたところ、良さげなモノができました。

#include "hgimg4.as" chdir dir_exe + "\\sample\\hgimg4" gpreset #module "my_mesh" ; モジュール初期化 #deffunc local _prism_init_ dim prm, 4 dim d1, 2 ddim v1 : ddim v2 : ddim v3 ddim x : ddim z ddim y, 2 : y = -0.5, 0.5 ddim nx : nx = 1.0 ddim ny : ny = 1.0 ddim nz : nz = 1.0 return ;=========================================================== ; 正n_poly角形のindex番目のx座標 ; #defcfunc p_cos int n_poly, int index return cos((M_PI * 2 * index) / n_poly) ;=========================================================== ; 正n_poly角形のindex番目のz座標 ; #defcfunc p_sin int n_poly, int index return sin((M_PI * 2 * index) / n_poly) ;=========================================================== ; 正多角柱 (正n角柱) ; [ var ] ID_var : 生成されたオブジェクトIDが代入される変数名 ; [ int ] color_ : マテリアルカラー (24bit RGB値) ; [ int ] n_poly : 底面の形状 (正n_poly角形) ; #deffunc prism var ID_var, int color_, int n_poly ; x, z座標の用意 ddim x, n_poly ddim z, n_poly repeat n_poly x(cnt) = p_cos(n_poly, cnt) z(cnt) = p_sin(n_poly, cnt) loop gpmeshclear ; mesh登録の初期化 ;----------------------------------- ; 角柱の側面 repeat (n_poly + 2) ; cnt番目 と (cnt + 1)番目 d1 = (cnt \ n_poly), ((cnt + 1) \ n_poly) prm(0) = ((0 < x(d1.0)) & (0 < x(d1.1))) prm(1) = ((x(d1.0) < 0) & (x(d1.1) < 0)) prm(2) = ((0 < z(d1.0)) & (0 < z(d1.1))) prm(3) = ((z(d1.0) < 0) & (z(d1.1) < 0)) if prm(0) {nx = 1.0 : nz = 0.0} else:if prm(1) {nx = -1.0 : nz = 0.0} else:if prm(2) {nx = 0.0 : nz = 1.0} else:if prm(3) {nx = 0.0 : nz = -1.0} ;--------------------------------------- ; 四角形の側面を三角形に分けて登録 repeat 2 gpmeshadd v1, x(d1.0), y(1), z(d1.0), nx, 0.0, nz gpmeshadd v2, x(d1.cnt), y(cnt), z(d1.cnt), nx, 0.0, nz gpmeshadd v3, x(d1.1), y(0), z(d1.1), nx, 0.0, nz if (cnt = 0) {gpmeshpolygon v1, v3, v2} ; 角柱の外側から見て右下 else:if (cnt = 1) {gpmeshpolygon v1, v2, v3} ; 角柱の外側から見て左上 ; v2 ----- v1 ; | / | ; | 1 / | ; | / | ; | / | ; | / 0 | ; | / | ; v3 ----- v2 loop loop ;----------------------------------- ; 角柱の底面 (上下2面) repeat 2 prm = cnt if (prm = 0) {y = 0.5 : ny = 1.0} ; 底面 (上) else:if (prm = 1) {y = -0.5 : ny = -1.0} ; 底面 (下) ;--------------------------------------- ; 1ホールのケーキをn等分するイメージ repeat n_poly ; cnt番目 と (cnt + 1)番目 d1 = (cnt \ n_poly), ((cnt + 1) \ n_poly) ; v1は半径0.5の円(単位円)の中心点 (0, 0) ; 直線"v1-v2" と 直線"v1-v3" を2辺とする二等辺三角形 gpmeshadd v1, 0.0, y, 0.0, 0.0, ny, 0.0 gpmeshadd v2, x(d1.0), y, z(d1.0), 0.0, ny, 0.0 gpmeshadd v3, x(d1.1), y, z(d1.1), 0.0, ny, 0.0 if (prm = 0) {gpmeshpolygon v1, v3, v2} ; 底面 (上) else:if (prm = 1) {gpmeshpolygon v1, v2, v3} ; 底面 (下) loop loop gpmesh ID_var, color_ return #global //// my_mesh //// _prism_init_@my_mesh ; モジュール初期化 ;########################################################### ; 以下サンプル ;########################################################### dim ID_Camera dim ID_Floor dim d1 : dim d2 dim posx, 9 dim ID_Prism, 9 dim color_set, 9 color_set(0) = 0xAA0000, 0x00AA00, 0x0000AA color_set(3) = 0xAA00AA, 0xAAAA00, 0x00AAAA color_set(6) = 0xA06060, 0x60A060, 0x6060A0 ;####################################### screen 0, 1280, 720 setcls CLSMODE_SOLID, 0x909090 ; 床 gpfloor ID_Floor, 50, 50, 0xB3B3B3 gppbind ID_Floor, 0 ; 多角柱 foreach ID_Prism prism ID_Prism(cnt), color_set(cnt), (3 + cnt) posx(cnt) = (2 * cnt) setpos ID_Prism(cnt), posx(cnt), 0.5, 0.0 loop ; カメラ ID_Camera = GPOBJ_CAMERA setpos ID_Camera, -5.0, 5.0, 5.0 gplookat ID_Camera, posx, 0.5, 0.0 ;####################################### *main await (1000.0 / 30.0) ;----------------------------------- stick key if ((key & 0x00080) ! 0) {end} ; ESC if ((key & 0x00400) ! 0) { ; TAB d1++ setpos ID_Camera, (-5.0 + posx(d1 \ 9)), 5.0, 5.0 gplookat ID_Camera, posx(d1 \ 9), 0.5, 0.0 } ;----------------------------------- gsel 0 redraw 0 gpdraw redraw 1 goto *main



この記事に返信する


YUZRANIUM

リンク

2023/7/7(Fri) 23:07:06|NO.99695

修正版です。


#include "hgimg4.as" chdir dir_exe + "\\sample\\hgimg4" gpreset #module "my_mesh" ;=========================================================== ; モジュール初期化 #deffunc local _prism_init_ dim prm, 4 dim d1, 2 ddim v1 : ddim v2 : ddim v3 : ddim v4 ddim nx : ddim ny : ddim nz nx = 1.0 : ny = 1.0 : nz = 1.0 ddim x : ddim z ddim y, 2 : y = -0.5, 0.5 return ;=========================================================== ; 正n_poly角形のindex番目のx座標 ; #defcfunc p_cos int n_poly, int index return cos((M_PI * 2 * index) / n_poly) ;=========================================================== ; 正n_poly角形のindex番目のz座標 ; #defcfunc p_sin int n_poly, int index return sin((M_PI * 2 * index) / n_poly) ;=========================================================== ; 正多角柱 (正n角柱) ; [ var ] ID_var : 生成されたオブジェクトIDが代入される変数名 ; [ int ] color_ : マテリアルカラー (24bit RGB値) ; [ int ] n_poly : 底面の形状 (正n_poly角形) ; #deffunc prism var ID_var, int color_, int n_poly ; x, z座標の用意 ddim x, n_poly ddim z, n_poly repeat n_poly x(cnt) = p_cos(n_poly, cnt) z(cnt) = p_sin(n_poly, cnt) loop gpmeshclear ; mesh登録の初期化 ;----------------------------------- ; 角柱の側面 repeat n_poly ; cnt番目 と (cnt + 1)番目 d1 = (cnt \ n_poly), ((cnt + 1) \ n_poly) ; 法線ベクトルの設定 if ((0 <= x(d1.0)) & (0 <= x(d1.1))) {nx = 1.0 : nz = 0.0} else:if ((0 <= z(d1.0)) & (0 <= z(d1.1))) {nx = 0.0 : nz = 1.0} else:if ((x(d1.0) < 0) & (x(d1.1) < 0)) {nx = -1.0 : nz = 0.0} else:if ((z(d1.0) < 0) & (z(d1.1) < 0)) {nx = 0.0 : nz = -1.0} ; 頂点登録 gpmeshadd v1, x(d1(0)), y(0), z(d1(0)), nx, 0.0, nz gpmeshadd v2, x(d1(0)), y(1), z(d1(0)), nx, 0.0, nz gpmeshadd v3, x(d1(1)), y(0), z(d1(1)), nx, 0.0, nz gpmeshadd v4, x(d1(1)), y(1), z(d1(1)), nx, 0.0, nz ; 面登録 gpmeshpolygon v1, v2, v3, v4 loop ;----------------------------------- ;----------------------------------- ; 角柱の底面 (上下2面) repeat 2 prm = cnt if (prm = 0) {y = 0.5 : ny = 1.0} ; 底面 (上) else:if (prm = 1) {y = -0.5 : ny = -1.0} ; 底面 (下) ;--------------------------------------- ; 1ホールのケーキをn等分するイメージ repeat n_poly ; cnt番目 と (cnt + 1)番目 d1 = (cnt \ n_poly), ((cnt + 1) \ n_poly) ; v1は半径0.5の円(単位円)の中心点 (0, 0) ; 直線"v1-v2" と 直線"v1-v3" を2辺とする二等辺三角形 gpmeshadd v1, 0.0, y, 0.0, 0.0, ny, 0.0 gpmeshadd v2, x(d1.0), y, z(d1.0), 0.0, ny, 0.0 gpmeshadd v3, x(d1.1), y, z(d1.1), 0.0, ny, 0.0 if (prm = 0) {gpmeshpolygon v1, v3, v2} ; 底面 (上) else:if (prm = 1) {gpmeshpolygon v1, v2, v3} ; 底面 (下) loop ;--------------------------------------- loop ;----------------------------------- gpmesh ID_var, color_ return #global //// my_mesh //// _prism_init_@my_mesh ; モジュール初期化 ;########################################################### ; 以下サンプル ;########################################################### #const A_key 0x04000 #const W_key 0x08000 #const D_key 0x10000 #const S_key 0x20000 dim ID_Camera dim ID_Floor dim ID_Prism, 9 dim color_set, 9 color_set(0) = 0xAA0000, 0x00AA00, 0x0000AA color_set(3) = 0xAA00AA, 0xAAAA00, 0x00AAAA color_set(6) = 0xA06060, 0x60A060, 0x6060A0 dim x, 3 : x = -4.2, 0.0, 4.2 dim z, 3 : z = -4.2, 0.0, 4.2 ;======================================== screen 0, 1280, 720 setcls CLSMODE_SOLID, 0x909090 ; 床 gpfloor ID_Floor, 50, 50, 0xB3B3B3 gppbind ID_Floor, 0 ; 多角柱 foreach ID_Prism prism ID_Prism(cnt), color_set(cnt), (3 + cnt) setpos ID_Prism(cnt), x(cnt / 3), 0.5, z(cnt \ 3) loop ; カメラ ID_Camera = GPOBJ_CAMERA setpos ID_Camera, -5.0, 4.0, 5.0 gplookat ID_Camera, 0.0, 0.5, 0.0 ;============= メインループ ============== *main await (1000.0 / 30.0) ;----------------------------------- ; キーコンフィグ stick key, (W_key + A_key + S_key + D_key) if ((key & 0x00080) ! 0) {end} ; ESC if ((key & W_key) ! 0) {addpos ID_Camera, 0.0, 0.0, 0.5} if ((key & S_key) ! 0) {addpos ID_Camera, 0.0, 0.0, -0.5} if ((key & A_key) ! 0) {addpos ID_Camera, 0.5, 0.0, 0.0} if ((key & D_key) ! 0) {addpos ID_Camera, -0.5, 0.0, 0.0} gplookat ID_Camera, 0.0, 0.5, 0.0 ;----------------------------------- ; 描画 gsel 0 redraw 0 gpdraw pos 10, 10 rgbcolor 0xC0C0C0 : boxf 5, 5, 110, 200 objcolor (255 / 2), (255 / 2), (255 / 2) foreach color_set rgbcolor color_set(cnt) : mes "正" + (3 + cnt) + "角形柱", 4 loop redraw 1 goto *main ;============= メインループ ==============



YUZRANIUM

リンク

2023/7/7(Fri) 23:15:06|NO.99696

2つの三角形として2回に分けて登録していた
角柱の側面を1回で済ませようにしました。


というのもHDL、gpmeshpolygonの項、頂点指定の順番の解説で
”p1, p2, p3の三角形を時計回りに〜”
といった文言にまんまと騙されてしまい(笑)行き詰まりそうになりました。

(まぁ、無事に犠牲者の一人にはなることができましたのでノルマ達成ですね(何が?))


この頂点指定順番の問題、過去版ではあちらこちらで見かけるようで
(といっても1年前...割と最近...)当時HOTな話題だったのですね。

個人的には、

1. メッシュの内側から (←なんとなく覚えやすかったので)
2. 大文字の"N"もしくは"Z"を
3. 一筆書きで書く

ような順番で指定する。と覚えてしまったので
今後、指定の順番で迷うことはないかも。

その証拠にrepeat〜loopにまで落とし込むことができましたし、
個人的には完成度6割というところでしょうか。



YUZRANIUM

リンク

2023/7/7(Fri) 23:23:26|NO.99697

あとは法線ベクトルですが、ひとまず置いておくとして

上面を点v1(0.0, 1.0, 0.0)のみにすることで角錐(錐体)、
座標算出時に別の配列変数に代入し、座標を縮小させてやれば錐台も作れそうですね。

頂点数を増やしていけば円柱、円錐、円錐台もいけそうですね。

他にも正五角形が作れるので、そこから星型(五芒星?)もできそうかも?

夢が広がりング



YUZRANIUM

リンク

2023/7/11(Tue) 23:16:40|NO.99718

修正版 改I

角柱・角錐・角錐台を生成できるようになりました。

prism命令 : 角柱
frustum命令 : 角柱・角錐・角錐台

64角形とか128角形にすると円柱・円錐・円錐台になります (そう見えるだけ)

法線ベクトルは専用の命令で計算できるように改良。(fvouterさいこー)

#include "hgimg4.as" chdir dir_exe + "\\sample\\hgimg4" gpreset #module "my_mesh" ;=========================================================== ; モジュール初期化 #deffunc local _prism_init_ ; 頂点番号 dim d1 : dim d2 ; メッシュ頂点ID用 ddim v1 : ddim v2 : ddim v3 : ddim v4 ; 頂点座標 ddim x : ddim y : ddim z : ddim x_top : ddim z_top return ;=========================================================== ; 正n_poly角形のindex番目のx座標 ; #defcfunc p_cos int n_poly, int index return cos((M_PI * 2 * index) / n_poly) ;=========================================================== ; 正n_poly角形のindex番目のz座標 ; #defcfunc p_sin int n_poly, int index return sin((M_PI * 2 * index) / n_poly) ;=========================================================== ; 法線ベクトル計算 ; #deffunc n_vector array normal, var vx_top, var vz_top, var vx_btm, var vz_btm, double scale_ fvset normal, vx_btm, -0.5, vz_btm fvouter normal, vx_top, 0.5, vz_top if ((1.0 < scale_) & (0.0 < normal.1)) {normal(1) *= -1} ; 頭でっかちは下向きに else:if ((scale_ < 1.0) & (normal.1 < 0.0)) {normal(1) *= -1} ; おしり大は上向きに else:if (scale_ = 1.0) {normal(1) = 0.0} return ;=========================================================== ; 側面の登録 ; [ int ] n_poly : 角数 ; [array] vx_top : 上面のx座標 ; [array] vz_top : 上面のz座標 ; [array] vx_btm : 下面のx座標 ; [array] vz_btm : 下面のz座標 ; #deffunc local v_asain_side int n_poly, \ array vx_top, array vz_top, array vx_btm, array vz_btm, double scale_ ddim fv ddim v1 : ddim v2 : ddim v3 : ddim v4 dim d1 : dim d2 ;----------------------------------- ; 角柱の側面 repeat n_poly ; cnt番目 と (cnt + 1)番目 d1 = (cnt \ n_poly) : d2 = ((cnt + 1) \ n_poly) ; 法線ベクトルの設定 n_vector fv, vx_top(d2), vz_top(d2), vx_btm(d1), vz_btm(d1), scale_ ; 頂点登録 gpmeshadd v1, vx_btm(d1), -0.5, vz_btm(d1), fv(0), fv(1), fv(2) gpmeshadd v2, vx_top(d1), 0.5, vz_top(d1), fv(0), fv(1), fv(2) gpmeshadd v3, vx_btm(d2), -0.5, vz_btm(d2), fv(0), fv(1), fv(2) gpmeshadd v4, vx_top(d2), 0.5, vz_top(d2), fv(0), fv(1), fv(2) ; 面登録 gpmeshpolygon v1, v2, v3, v4 loop ;----------------------------------- return ;=========================================================== ; 底面の登録 ; [ int ] n_poly : 角数 ; [array] vx_btm : 下面のx座標 ; [array] vz_btm : 下面のz座標 ; [ int ] mode : 登録モード (= 0, 0:上面 / 1:下面) ; #deffunc local v_asain_btm int n_poly, array vx_btm, array vz_btm, int mode ddim y : ddim ny dim d1 : dim d2 if (mode = 0) {y = 0.5 : ny = 1.0} ; 上面 else:if (mode = 1) {y = -0.5 : ny = -1.0} ; 下面 ;--------------------------------------- ; 1ホールのケーキをn等分するイメージ repeat n_poly ; cnt番目 と (cnt + 1)番目 d1 = (cnt \ n_poly) : d2 = ((cnt + 1) \ n_poly) ; v1は半径0.5の円(単位円)の中心点 (0, 0) ; 直線"v1-v2" と 直線"v1-v3" を2辺とする二等辺三角形 gpmeshadd v1, 0.0, y, 0.0, 0.0, ny, 0.0 gpmeshadd v2, vx_btm(d1), y, vz_btm(d1), 0.0, ny, 0.0 gpmeshadd v3, vx_btm(d2), y, vz_btm(d2), 0.0, ny, 0.0 ; 面登録 if (mode = 0) {gpmeshpolygon v1, v3, v2} ; 上面 else:if (mode = 1) {gpmeshpolygon v1, v2, v3} ; 下面 loop ;--------------------------------------- return ;=========================================================== ; 正多角柱 ; [ var ] ID_var : 生成されたオブジェクトIDが代入される変数名 ; [ int ] color_ : マテリアルカラー (24bit RGB値) ; [ int ] n_poly : 底面の形状 (正n_poly角形) ; #deffunc prism var ID_var, int color_, int n_poly ; x, z座標の用意 ddim x, n_poly ddim z, n_poly repeat n_poly x(cnt) = p_cos(n_poly, cnt) z(cnt) = p_sin(n_poly, cnt) loop gpmeshclear ; mesh登録の初期化 ;----------------------------------- ; 角柱の側面 v_asain_side@my_mesh n_poly, x, z, x, z, 1.0 ;----------------------------------- ; 角柱の底面 (上) v_asain_btm@my_mesh n_poly, x, z, 0 ;----------------------------------- ; 角柱の底面 (下) v_asain_btm@my_mesh n_poly, x, z, 1 ; mesh登録 gpmesh ID_var, color_ ddim x : ddim z return ;=========================================================== ; 正多角錐 / 錐台 ; [ var ] ID_var : 生成されたオブジェクトIDが代入される変数名 ; [ int ] color_ : マテリアルカラー (24bit RGB値) ; [ int ] n_poly : 底面の形状 (正n_poly角形) ; [double] scale_ : 上面のXZ平面のスケール (1.0で底面と同じ) ; #deffunc frustum var ID_var, int color_, int n_poly, double scale_ ; x, z座標の用意 ddim x_top, n_poly : ddim x, n_poly ddim z_top, n_poly : ddim z, n_poly repeat n_poly x(cnt) = p_cos(n_poly, cnt) z(cnt) = p_sin(n_poly, cnt) x_top(cnt) = scale_ * x(cnt) z_top(cnt) = scale_ * z(cnt) loop gpmeshclear ; mesh登録の初期化 ;----------------------------------- ; 角柱の側面 v_asain_side@my_mesh n_poly, x_top, z_top, x, z, scale_ ;----------------------------------- ; 角柱の底面 (上) v_asain_btm@my_mesh n_poly, x_top, z_top, 0 ;----------------------------------- ; 角柱の底面 (下) v_asain_btm@my_mesh n_poly, x, z, 1 ; mesh登録 gpmesh ID_var, color_ ddim x_top : ddim x ddim z_top : ddim z return #global //////// my_mesh //////// _prism_init_@my_mesh ; モジュール初期化 ;########################################################### ; 以下サンプル ;########################################################### #const A_key 0x04000 #const W_key 0x08000 #const D_key 0x10000 #const S_key 0x20000 #const Z_key 0x00800 #const X_key 0x01000 dim ID_Camera dim ID_Prism, 9 : dim ID_Frustum, 9 : dim ID_Corn, 9 dim color_set, 9 color_set(0) = 0xAA0000, 0x00AA00, 0x0000AA color_set(3) = 0xAA00AA, 0xAAAA00, 0x00AAAA color_set(6) = 0xA06060, 0x60A060, 0x6060A0 ddim pos_, 3 : pos_ = -4.2, 0.0, 4.2 ddim x : ddim z ;================================================ screen 0, 1280, 720 setcls CLSMODE_SOLID, 0x909090 ; 多角柱 foreach ID_Prism ; オブジェクト生成 prism ID_Prism(cnt), color_set(cnt), (3 + cnt) ; 多角柱 frustum ID_Frustum(cnt), color_set(cnt), (3 + cnt), 0.30 ; 錐台 frustum ID_Corn(cnt), color_set(cnt), (3 + cnt), 0.00 ; 錐 x = pos_(cnt / 3) : z = pos_(cnt \ 3) setpos ID_Prism(cnt), x, 0.0, z setpos ID_Frustum(cnt), x, -4.2, z setpos ID_Corn(cnt), x, 4.2, z loop ; カメラ ID_Camera = GPOBJ_CAMERA setpos ID_Camera, -5.0, 4.0, 5.0 gplookat ID_Camera, 0.0, 0.5, 0.0 objcolor (255 / 2), (255 / 2), (255 / 2) ;================================================ *main await (1000.0 / 60.0) ;----------------------------------- stick key, (W_key + A_key + S_key + D_key + Z_key + X_key) if ((key & 0x00080) ! 0) {end} ; ESC ddim campos, 3 if ((key & W_key) ! 0) {campos(2) = 0.5} if ((key & S_key) ! 0) {campos(2) = -0.5} if ((key & A_key) ! 0) {campos(0) = 0.5} if ((key & D_key) ! 0) {campos(0) = -0.5} if ((key & Z_key) ! 0) {campos(1) = 0.5} if ((key & X_key) ! 0) {campos(1) = -0.5} addpos ID_Camera, campos(0), campos(1), campos(2) gplookat ID_Camera, 0.0, 0.5, 0.0 ;----------------------------------- gsel 0 redraw 0 gpdraw pos 10, 10 rgbcolor 0xC0C0C0 : boxf 5, 5, 110, 200 rgbcolor 0x000000 : mes "底面の形状" foreach color_set rgbcolor color_set(cnt) : mes "正" + (3 + cnt) + "角形", 4 loop redraw 1 goto *main



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