0

私はScalaに関数を持っていて、JavaScriptにも同じ関数を持っていますが、それが機能的なスタイルではないと思います。

def drawSurroundingTriangles(startx : Double, starty : Double, width : Double) {
    var newwidth = width/2;
    var newstartx = startx + newwidth / 2;
    var newstarty = starty - newwidth;
    drawTriangle(newstartx, newstarty, newwidth);
    drawTriangle(newstartx - newwidth, starty + newwidth, newwidth);
    drawTriangle(newstartx + newwidth, starty + newwidth, newwidth);
    if(newwidth < 6)
        return;
    drawSurroundingTriangles(newstartx, newstarty, newwidth);
    drawSurroundingTriangles(newstartx - newwidth, starty + newwidth, newwidth);
    drawSurroundingTriangles(newstartx + newwidth, starty + newwidth, newwidth);
}

私の望みは、これを再帰的にするのではなく、反復子にすることです。そうすれば、次の反復を取得し続けることができ、次のレベルが出力されるので、プログラムは最初に外側の三角形を作成し、次に最初の内側の三角形を描画します。それをイテレータにすることで、キーが押されて次の反復が行われるのを待つことができ、おそらく毎回色が変わります。

その後、この関数に到達し、そこでループします。各反復で次のようになります。

  1. 中央の三角形の両側に1つずつ、合計3つの三角形を描画します
  2. 前の反復からの3つの三角形の両側に1つずつ、合計9つの三角形を描画します。
  3. 27個の三角形を描く

..。

アップデート:

すみません、クエスチョンマークを忘れてしまい、見づらいです。

基本的には、再帰関数からオンデマンドで呼び出せる関数に変更して、次の反復を描画してもらいたいと思います。 どうやってやるの?

アップデート2:

私にはうまくいく解決策がありますが、どちらの解決策が良いのか、私のものか、この質問の答えでもあるのかわかりません:

def drawSurroundingTriangles(indexlist : List[(Double, Double, Double)]) : List[(Double, Double, Double)] = {
    var mylist = ListBuffer[(Double, Double, Double)]()
    indexlist.foreach{ 
        case (startx, starty, width) => { mylist ++ drawSingleTriangle(startx, starty, width) } }

    mylist.toList;
}

def drawSingleTriangle(startx : Double, starty : Double, width : Double) : List[(Double, Double, Double)] = {
    val newwidth = width/2;
    val newstartx = startx + newwidth / 2;
    val newstarty = starty - newwidth;
    var list = List((newstartx, newstarty, newwidth),
            ((newstartx - newwidth, starty + newwidth, newwidth)),
            (newstartx + newwidth, starty + newwidth, newwidth));
    list.foreach{ case (nstartx, nstarty, nwidth) => drawTriangle(nstartx, nstarty, nwidth)}
    list;
}
4

4 に答える 4

2

関数がペアを返すようにします。左半分には、現在の反復の三角形が含まれています。右半分には、次の反復と関数の三角形を含むペアを返す関数が含まれています...

編集ソリューションを書き換える方法は次のとおりです。

type Triangle = (Double, Double, Double)

def fractal(width : Double): Stream[List[Triangle]] = {
  val w2 = width / 2
  def surrounding(t: Triangle) = match t case (startx, starty, width) => {
    val w = width/2
    val x = startx + w / 2
    val y = starty - w
    List((x, y, w),
         (x - w, starty + w, w),
         (x + w, starty + w, w))
  }
  def s(tris: List[Triangle]): Stream[List[Triangle]] =
    Stream.cons(tris, s(tris.flatMap(surrounding(_))))
  s(List((w2/2, w2, w2)))
}

私はこれを試していませんが、この効果に非常に大きな影響を与えるものは、反復のストリームを提供します。各反復は三角形のリストです。反復を描画するには、ストリームからポップして、それを呼び出しますdrawTriangle

スタイルのヒント: は避けてくださいforeach。タブの代わりに 2 つまたは 3 つのスペースを使用します。簡潔な名前を使用すると、コードの構造をスキャンしやすくなります。セミコロンは不要なノイズです。

于 2009-11-15T08:42:09.240 に答える
1

ストリームは、無限の可能性があるシーケンスの遅延計算をカプセル化します。それらを扱うのは難しいかもしれませんが、少なくとも驚くべきことかもしれませんが、あなたの要件には合っています. Scaladoc を確認し、ブログを探し、Scala メーリング リストのアーカイブを検索して、怠惰であることが何を意味するかを十分に理解していない場合の使用や、2.7 ライブラリの実装上の欠陥をめぐる多くの悲惨な話を探してください。 ..

あいまいで申し訳ありませんが、一度使用したことがありますが、より具体的にしようとする資格はありません...

ランドール・シュルツ

于 2009-11-14T17:11:43.183 に答える
0

これが私がたどり着いた最終的な答えですが、Aposcalisp からの答えを除いて、カリー化された関数について考えたことはありませんでした。

これを改善するために特性を使用する必要があるかどうかはわかりませんが、これが反復する最良の方法だと思います。

def drawFractal(width : Double) {
    val mywidth = width / 2;
    val drawSurroundingTriangles = drawSurroundingTrianglesComplete((startx, starty, width) => {
            val newwidth = width/2;
            val newstartx = startx + newwidth / 2;
            val newstarty = starty - newwidth;
            var list = List((newstartx, newstarty, newwidth),
                    ((newstartx - newwidth, starty + newwidth, newwidth)),
                    (newstartx + newwidth, starty + newwidth, newwidth));
            list.foreach{ case (nstartx, nstarty, nwidth) => drawTriangle(nstartx, nstarty, nwidth)}
            list;
    })_

    var mylist = drawSurroundingTriangles(List((mywidth/2, mywidth, mywidth)));
    mylist.foreach{ case (startx, starty, width) => print ("[" + startx + "," + starty + "," + width + "]\n")}
    print("\n");
    mylist = drawSurroundingTriangles(mylist);
    mylist.foreach{ case (startx, starty, width) => print ("[" + startx + "," + starty + "," + width + "]\n")}
}
def drawSurroundingTrianglesComplete(myfunc : (Double, Double, Double) => List[(Double, Double, Double)])
(indexlist : List[(Double, Double, Double)]) : 
    List[(Double, Double, Double)] = {
    var mylist = ListBuffer[(Double, Double, Double)]()
    indexlist.foreach{ 
        case (startx, starty, width) => { mylist ++= myfunc(startx, starty, width) } }
    mylist.toList;
}
于 2009-11-16T04:51:07.547 に答える