質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.34%

ループで反時計回りの線分でぐるりと一周囲まれた内部を塗りつぶしたいです。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 517

score 29

プチコン3号で反時計回りの線分でぐるりと一周囲まれた内部をループで塗りつぶしたいです。
何故ならば、いちいち一つの頂点枚に計算していたら冗長すぎて面倒です。
そこで配列とループで出来ないかどうか知りたいです。

以下のプログラムをループで求めたいです。
これを何に使いたいかというと応用としてレーシングゲームでコースアウトしたかどうかを
知りたいのです。

以下実行結果です。
リンク内容

DIM LINEX[4]:DIM LINEY[4]'LINE ノ X ト Y
ADD=80 'ホセイチ

LINEX[0]=50/2+ADD:LINEY[0]=20/2+ADD
LINEX[1]=10/2+ADD:LINEY[1]=200/2+ADD
LINEX[2]=380/2+ADD:LINEY[2]=230/2+ADD
LINEX[3]=320/2+ADD:LINEY[3]=30/2+ADD

DIM S[4]
GCLS 'ガメンヲショウキョ
MINX=MIN(LINEX):MINY=MIN(LINEY) 'サイショウチノ X ト Y
MAXX=MAX(LINEX):MAXY=MAX(LINEY) 'サイダイチノ X ト Y

FOR Y2=MINY TO MAXY
FOR X2=MINX TO MAXX
TX=X2:TY=Y2
GOSUB @L
IF ANS1<0 && ANS2<0 && ANS3<0 && ANS4<0 THEN GPSET X2,Y2 
'ANS1トANS2トANS3トANS4ガ0ヨリシタナラGPSETデ テン ヲ エガク
NEXT
NEXT
END

@L 'ココカラ シタヲ ループデ モトメタイ
VX1=(LINEX[1]-LINEX[0])
VY1=(LINEY[1]-LINEY[0])
VX2=TX-LINEX[0]
VY2=TY-LINEY[0]
ANS1=VX1*VY2-VY1*VX2

VX1=(LINEX[2]-LINEX[1])
VY1=(LINEY[2]-LINEY[1])
VX2=TX-LINEX[1]
VY2=TY-LINEY[1]
ANS2=VX1*VY2-VY1*VX2

VX1=(LINEX[3]-LINEX[2])
VY1=(LINEY[3]-LINEY[2])
VX2=TX-LINEX[2]
VY2=TY-LINEY[2]
ANS3=VX1*VY2-VY1*VX2

VX1=(LINEX[0]-LINEX[3])
VY1=(LINEY[0]-LINEY[3])
VX2=TX-LINEX[3]
VY2=TY-LINEY[3]
ANS4=VX1*VY2-VY1*VX2

GLINE LINEX[0],LINEY[0],LINEX[1],LINEY[1]
GLINE LINEX[1],LINEY[1],LINEX[2],LINEY[2]
GLINE LINEX[2],LINEY[2],LINEX[3],LINEY[3]
GLINE LINEX[3],LINEY[3],LINEX[0],LINEY[0]

RETURN

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • littlestream

    2020/03/27 18:11

    6502CPUはギリギリ自分もファミコン世代なので
    カービィとかくにおくんとか、マリオとかよくやりました。
    で、大人になってからインターネットが発達して
    ギコ猫でもわかるファミコンプログラミングというサイトで勉強して、6502の基本を覚えました。
    PC-エンジンやスーパーファミコンにもノウハウの継承が(一部だけ)出来たのは心強かったです。
    (一行ずつ書いていたら行数が多くなってしまうのでこういう書き方は本来良くないのですが)
    LDA #$3F、STA $2006、LDA #$00、STA $2006、
    LDX #0、.LOOP LDA PAL,X、STA $2007、INX、CPX #32、BNE .LOOPとか、
    LDX #0,LDY #0、STX $2005、STY $2005とか、
    よくI/Oレジスタも覚えてたりしたのですが、
    今でもスクロールしながらBG書き換えが出来なかったりします。

    キャンセル

  • x_x

    2020/03/27 19:05

    せっかくの「SMILEBASIC」タグですがタグ説明が残念なことになっていますね……

    キャンセル

  • littlestream

    2020/03/27 19:25

    >x_xさん
    SMILEBASICじゃなくてPETIT COMPUTERと入れるべきだったでしょうか。。。

    キャンセル

回答 2

check解決した方法

0

こんな感じです。何かマズい点がありましたらご指摘お願いします。

'カイトウ ノ イチレイ ニ ナレバ サイワイ デス.
DIM POLYX[10]:DIM POLYY[10]
DIM POLYX2[10]:DIM POLYY2[10]
DIM LEFT[240]:DIM RIGHT[240]'プチコン ノ タテ ノ カイゾウド ハ x=0-400,y=0-240
Z80=65816 'Z ハチマル CPU ト スーパーファミコン ノ 65816 CPU
JX=0:JY=0
GCLS 'ガメン ノ ショウキョ
INX=0:INX2=0
@INIT
INPUTPOLY 100,20
INPUTPOLY 45,120
INPUTPOLY 80,230
INPUTPOLY 160,220
INPUTPOLY 200,140
'ソトガワ ノ チョウテン ノ ダイニュウ

INPUTPOLY2 100,80
INPUTPOLY2 60,120
INPUTPOLY2 80,200
INPUTPOLY2 160,195
INPUTPOLY2 150,120
'ウチガワ ノ チョウテン ノ ダイニュウ
@MAIN
GCLS

FOR I=0 TO 240-1
   LEFT[I]=Z80
   MINX[I]=Z80
   RIGHT[I]=-Z80
   MAXX[I]=-Z80
NEXT

SCANX POLYX[0],POLYY[0],POLYX[1],POLYY[1]
SCANX POLYX[1],POLYY[1],POLYX[2],POLYY[2]
SCANX POLYX[2],POLYY[2],POLYX[3],POLYY[3]
SCANX POLYX[3],POLYY[3],POLYX[4],POLYY[4]
SCANX POLYX[4],POLYY[4],POLYX[0],POLYY[0]

SCANX2 POLYX2[0],POLYY2[0],POLYX2[1],POLYY2[1]
SCANX2 POLYX2[1],POLYY2[1],POLYX2[2],POLYY2[2]
SCANX2 POLYX2[2],POLYY2[2],POLYX2[3],POLYY2[3]
SCANX2 POLYX2[3],POLYY2[3],POLYX2[4],POLYY2[4]
SCANX2 POLYX2[4],POLYY2[4],POLYX2[0],POLYY2[0]

@MAIN2
GCLS 'グラフィック ガメン ノ ショウキョ
CLS 'キャラクター ガメン ノ ショウキョ

IF (BUTTON(0)AND 1)==1 THEN JY=JY-2 'UE
IF (BUTTON(0)AND 2)==2 THEN JY=JY+2 'SITA
IF (BUTTON(0)AND 4)==4 THEN JX=JX-2 'LEFT
IF (BUTTON(0)AND 8)==8 THEN JX=JX+2 'RIGHT

MINY=MIN(POLYY)
MAXY=MAX(POLYY)

FOR Y=0 TO 240-1

    IF LEFT[Y]==Z80 && RIGHT[Y]==-Z80 THEN CONTINUE
    GLINE LEFT[Y],Y,RIGHT[Y],Y,RGB(0,255,0) 'LEFT TO RIGHT

    IF LEFT[Y]<JY && JX<RIGHT[Y] && JY==Y && !(MINX[Y]<JX && JX<MAXX[Y]) THEN LOCATE 100/8,0:COLOR 3:PRINT "IN!"

NEXT

GCIRCLE JX,JY,2,RGB(255,0,255) 'エン(クルマ ノ ツモリ) ヲ エガク(カソクド トカ マサツケイスウ ハ アトデ カンガエル)

GLINE POLYX2[0],POLYY2[0],POLYX2[1],POLYY2[1]
GLINE POLYX2[1],POLYY2[1],POLYX2[2],POLYY2[2]
GLINE POLYX2[2],POLYY2[2],POLYX2[3],POLYY2[3]
GLINE POLYX2[3],POLYY2[3],POLYX2[4],POLYY2[4]
GLINE POLYX2[4],POLYY2[4],POLYX2[0],POLYY2[0]

VSYNC 2

GOTO @MAIN2

DEF SCANX X1,Y1,X2,Y2
   FOR I=0 TO 512
      X=(X1*(512-I)+X2*I)/512
      Y=(Y1*(512-I)+Y2*I)/512
      IF RIGHT[Y]<X THEN RIGHT[Y]=X
      IF LEFT[Y]>X THEN LEFT[Y]=X
   NEXT
END

'SCANX2 モ SCANX ト ドウヨウ ニ MINX ト MAXX ヲ モトメル

DEF INPUTPOLY X,Y
   POLYX[INX]=X
   POLYY[INX]=Y

   INX=INX+1
END

DEF INPUTPOLY2 X,Y
   POLYX2[INX2]=X
   POLYY2[INX2]=Y

   INX2=INX2+1
END

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/29 13:11

    FOR Y=0 TO 240-1

    IF LEFT[Y]==Z80 && RIGHT[Y]==-Z80 THEN CONTINUE
    GLINE LEFT[Y],Y,RIGHT[Y],Y,RGB(0,255,0) 'LEFT TO RIGHT①

    IF LEFT[Y]<JY && JX<RIGHT[Y] && JY==Y && !(MINX[Y]<JX && JX<MAXX[Y]) THEN LOCATE 100/8,0:COLOR 3:PRINT "IN!"'②

    NEXT

    以上の①は塗りつぶしを行う部分ですが、コースアウトを判定する②は、よく考えると
    IF LEFT[JY]<JY && JX<RIGHT[JY] && !(MINX[JY]<JX && JX<MAXX[JY]) THEN LOCATE 100/8,0:COLOR 3:PRINT "IN!"'②改
    とすればいちいちスキャンラインを使う必要はなくなるばかりか、塗りつぶしを行うコストもなくなります。これで、コースアウトの判定は大分分かってきたので解決といたします。

    キャンセル

  • 2020/03/29 13:19

    FOR Y=0 TO 240-1と
    NEXTは要らないのと、GLINEとIF LEFT[Y]==Z80...CONTINUEも要らないです。

    キャンセル

0

直面している問題点(というか解決すべき課題)が何なのかイマイチわかりませんが…

凸包(←提示コードからそうだと判断)の塗りつぶしであれば,普通に

  • 三角形を塗りつぶす処理を用意する
  • 凸包を複数の三角形に分割して↑を利用して塗る

ではダメなのでしょうか?


(本質は「塗りつぶし処理」ではなく,多角形の内外判定だということですので…)

とりあえず多角形が凸であるならば,
判定したい点を通る直線と多角形との交点を求めて,位置関係から判断する方法が割と有名(?)かと思います.
(実際やってみると面倒な事柄が出てきたりはしますが)

  • 交点が2点無ければ,少なくとも「内側」ではない
  • 交点が2点ある場合,判定したい点が2点の間であれば「内側」

図

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/27 12:25

    https://youtu.be/p_5StvtX1_k
    上のURLに実行中の画面を載せました。
    只今外出中なのでスマホから書き込んでおり2DSのプチコン3号で実装しました。ソースコードは、帰宅時にしばらくしてから載せます。

    キャンセル

  • 2020/03/27 12:34

    > 今回はポリゴンの描画の自作ソースを参考にしてみました。

    状況がよくわかりませんが,実施されている事柄がこの回答と関係ない(関係が薄い,アルゴリズムが異なる,etc)ようであれば,このサイトの使い方としては,自己解決的(自分の質問に自分で回答を書いて,それをBAにする)な形にすると良いのかと思います.

    キャンセル

  • 2020/03/27 18:14

    分かりました。先ほど帰宅して夕食を食べ終わった所です。
    自分としては、回答を元に自分のソースを弄りながら作ったので自分の質問に自分で
    回答に書いてみて、これだと、こういう部分がマズい、とかご指摘がありましたら宜しくお願いします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る