GDIを利用した多角形描画。#include "gdi32.as"
cls 4
CreatePen 0, 3, 0xffff00
if stat {
hPen = stat
} else {
end
}
CreateSolidBrush 0xff0000
if stat {
hBrush = stat
} else {
end
}
points = 50, 50, 150, 100, 100, 150
SelectObject hDC, hPen
SelectObject hDC, hBrush
Polygon hDC, varptr(points), 3
DeleteObject hPen
DeleteObject hBrush
redraw 1
stop
2007年5月7日月曜日
多角形の描画
2007年5月6日日曜日
リサージュ曲線を描画する
リサージュ曲線を描画するスクリプト。#const RADIUS 200
#const PI 3.14159
a = 3
b = 2
posCenterX = double(RADIUS + 50)
posCenterY = double(RADIUS + 50)
screen 0, posCenterX * 2, posCenterY * 2
i = 0.0
pos posCenterX + RADIUS, posCenterY
while i <= PI * 2
line posCenterX + cos(i * a) * RADIUS, posCenterY - sin(i * b) * RADIUS
i += 0.01
; await 1
wend
title "finish"
stop
最大公約数と最大公倍数を求める
// 最大公約数(GCD)と最小公倍数(LCM)を求めるユーザー定義関数
#module GetGCDandLCM
#defcfunc _gcd int high, int low, local tmp
tmp = high \ low
if tmp {
return _gcd(low, tmp)
} else {
return low
}
#defcfunc gcd int i1, int i2
if i1 > i2 {
return _gcd(i1, i2)
} else {
return _gcd(i2, i1)
}
#defcfunc lcm int i1, int i2
return i1 * i2 / gcd(i1, i2)
#global
// 以下サンプル
#runtime "hsp3cl"
mes "最大公約数と最小公倍数を求める整数を2つ入力してください..."
repeat 2
repeat
input tmp, , 1
if int(tmp) > 0 : break
mes "1以上の整数値を入力してください..."
loop
num(cnt) = int(tmp)
loop
mes "GCD(" + num(0) + ", " + num(1) + ") = " + gcd(num(0), num(1))
mes "LCM(" + num(0) + ", " + num(1) + ") = " + lcm(num(0), num(1))
stop
2007年5月5日土曜日
ベジェ曲線
ベジェ曲線を描画する。
2つ目以降のベジェ曲線は、1つ前のベジェ曲線の終点を始点とする。
参考
- http://musashi.or.tv/fontguide_doc3.htm
// 3次のベジェ曲線 for HSP3
#module Bezier
// 3次のベジェ曲線を描画
// (x1, y1)と(x4, y4)が端点、(x2, y2)と(x3, y3)が方向点
#deffunc bzArgo int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, local t, local k, local lx, local ly
pos x1, y1
repeat 100, 1
t = double(cnt)/100
k = 1.0 - t
lx = k * k * k * x1 + 3.0 * k * k * t * x2 + 3.0 * k * t * t * x3 + t * t * t * x4
ly = k * k * k * y1 + 3.0 * k * k * t * y2 + 3.0 * k * t * t * y3 + t * t * t * y4
line lx, ly
loop
return
// 制御点を4つづつ区切り、bzArgoに渡す
#deffunc bzDrawLine
repeat (count - 1)/3
bzArgo x(cnt*3), y(cnt*3), x(cnt*3 + 1), y(cnt*3 + 1), x(cnt*3 + 2), y(cnt*3 + 2), x(cnt*3 + 3), y(cnt*3 + 3)
loop
return
// 点を描画
#deffunc bzDrawPoint
repeat count
circle x(cnt) - 2, y(cnt) - 2, x(cnt) + 2, y(cnt) + 2
loop
return
// 点を追加
#deffunc bzAdd int x1, int y1
x(count) = x1 : y(count) = y1
count++
return count
#deffunc bzClear
count = 0
dim x, 1 : dim y, 1
cls 4
return
#global
bzClear
onclick *addPoint
stop
// 左クリックで制御点を追加、右クリックで制御点を削除
*addPoint
if iparam == 0 {
bzAdd lparam & $FFFF, lparam >> 16
redraw 0
color : boxf
color 255
bzDrawPoint
color 255, 255, 255
bzDrawLine
redraw
} else {
if iparam == 3 : bzClear
}
stop
2007年5月4日金曜日
砲弾の射出(d3module)
目標地点を指定すると、そのために必要な射出方向を計算する。
射出速度は一定なので、遠方を狙うほど早く着弾する。// ang ... 角度, pos ... 位置(座標), velo... 速さ
// distance ... 距離, b ... 放物線の第2係数
#include "d3m.hsp"
#module powModule
#defcfunc pow double d1, int i2, local st
st = 1.0
repeat i2
st *= d1
loop
return st
#global
#const GRAVITY 1.0 // 重力加速度
#const VELOCITY 30.1 // 射出速度
#const DISTANCE_MAX VELOCITY * VELOCITY / GRAVITY // 最大飛距離
#const GRID_MAX 8 // グリッドの本数
#const GRID_DISTANCE 100 // グリッドの間隔
#const TARGET_RADIUS 10 // 照準の半径
#const BULLET_RADIUS 8 // 砲弾の半径
screen 0, 480, 480
// 射出点の座標
posCannonX = double(GRID_MAX) * GRID_DISTANCE / 2
posCannonY = 0.0
posCannonZ = 0.0
// 照準の座標
posTargetX = double(GRID_MAX) * GRID_DISTANCE / 2
posTargetY = double(GRID_MAX) * GRID_DISTANCE / 2
posTargetZ = 0.0
d3setcam GRID_MAX * GRID_DISTANCE / 2, -300, 200, GRID_MAX * GRID_DISTANCE / 2, GRID_MAX * GRID_DISTANCE / 2, 0
*main
gosub *move
gosub *draw
wait 4
goto *main
*move
stick key, 15
if key & 16 : gosub *shot
// 照準の移動
posTargetX += 10 * (((key >> 2) & 1) - (key & 1))
posTargetY += 10 * (((key >> 1) & 1) - ((key >> 3) & 1))
// 砲弾の移動
if posBulletZ >= 0 {
posBulletX += veloBulletX
posBulletY += veloBulletY
posBulletZ += veloBulletZ
veloBulletZ -= GRAVITY
}
return
*shot
// 射出 ここらへんのスクリプトの理解は力学と微分の知識が要ります
posBulletX = posCannonX
posBulletY = posCannonY
posBulletZ = posCannonZ
angBullet = atan(posTargetY - posCannonY, posTargetX - posCannonX)
distance = limitf(sqrt(pow(posTargetX - posCannonX, 2) + pow(posTargetY - posCannonY, 2)), 0.0, DISTANCE_MAX)
b = DISTANCE_MAX / distance + sqrt(pow(DISTANCE_MAX / distance, 2) - 1)
veloBulletR = sqrt(GRAVITY * distance / b / 2)
veloBulletZ = b * veloBulletR
veloBulletX = veloBulletR * cos(angBullet)
veloBulletY = veloBulletR * sin(angBullet)
return
*draw
redraw 0
color : boxf
color 0, 255 // グリッド
repeat GRID_MAX + 1
d3line cnt * GRID_DISTANCE, 0, 0, cnt * GRID_DISTANCE, GRID_MAX * GRID_DISTANCE, 0
d3line 0, cnt * GRID_DISTANCE, 0, GRID_MAX * GRID_DISTANCE, cnt * GRID_DISTANCE, 0
loop
color 255 // 照準
d3circle posTargetX, posTargetY, posTargetZ, TARGET_RADIUS, 0
if posBulletZ >= 0 {
color 0, 0, 255 // 砲弾
d3circle posBulletX, posBulletY, posBulletZ, BULLET_RADIUS
color 191, 191, 191 // 影
d3circle posBulletX, posBulletY, 0, BULLET_RADIUS
}
redraw 1
return
素数を任意の個数だけ出力

素数を任意の個数だけ出力するスクリプト。
検索を開始する数値を指定可能。
ちょっぴりフールプルーフ。#runtime "hsp3cl"
#module
#defcfunc prime int num
result = 1
repeat (num + 1)/2 - 1, 2
if (num \ cnt) == 0 : result = 0 : break
loop
return result
#global
repeat
mes "素数をいくつ出力しますか?"
input many, , 1
if int(many) > 0 : break
mes "1以上の整数値を入力してください..."
loop
repeat
mes "いくつから調べ始めますか?"
input start, , 1
if int(start) > 1 : break
mes "2以上の整数値を入力してください..."
loop
many = int(many)
mes str(many) + "個の素数を出力します..."
i = 0
repeat -1, int(start)
if prime(cnt) {
mes cnt
i++
if i == many : break
}
loop
mes "終了しました。"
end
2次のBスプライン関数による曲線
2次のBスプライン関数を描画する。// 2次のBスプライン関数 for HSP3
#module BSpline
// 2次のBスプライン関数を描画
// (x1, y1)と(x3, y3)がオンカーブ点、(x2, y2)がオフカーブ点
#deffunc bsArgo int x1, int y1, int x2, int y2, int x3, int y3, local k, local t
pos x1, y1
repeat 100, 1
t = double(cnt)/100
k = 1.0 - t
line k * k * x1 + 2.0 * t * k * x2 + t * t * x3, k * k * y1 + 2.0 * t * k * y2 + t * t * y3
loop
return
// オンカーブ点を算出し、bsArgoへ渡す
#deffunc bsDrawLine local xCurrent, local yCurrent
if count > 3 {
bsArgo x(0), y(0), x(1), y(1), (x(1) + x(2))/2, (y(1) + y(2))/2
xCurrent = (x(1) + x(2))/2 : yCurrent = (y(1) + y(2))/2
repeat count - 4, 2
xNext = (x(cnt) + x(cnt + 1))/2 : yNext = (y(cnt) + y(cnt + 1))/2
bsArgo xCurrent, yCurrent, x(cnt), y(cnt), xNext, yNext
xCurrent = xNext : yCurrent = yNext
loop
bsArgo xCurrent, yCurrent, x(count - 2), y(count - 2), x(count - 1), y(count - 1)
} else {
if count == 3 : bsArgo x(0), y(0), x(1), y(1), x(2), y(2)
}
return
// 点を描画
#deffunc bsDrawPoint
repeat count
circle x(cnt) - 2, y(cnt) - 2, x(cnt) + 2, y(cnt) + 2
loop
return
// 点を追加 最初と最後がオンカーブ点、それ以外はオフカーブ点になる
#deffunc bsAdd int x1, int y1
x(count) = x1 : y(count) = y1
count++
return count
#deffunc bsClear
count = 0
dim x, 1 : dim y, 1
cls 4
return
#global
bsClear
onclick *addPoint
stop
// 左クリックで制御点を追加、右クリックで制御点を削除
*addPoint
if iparam == 0 {
bsAdd lparam & $FFFF, lparam >> 16
redraw 0
color : boxf
color 255
bsDrawPoint
color 255, 255, 255
bsDrawLine
redraw
} else {
if iparam == 3 : bsClear
}
stop

