私はSFMLとC ++でのコーディングを使用しています。私が書いているプログラムは再帰的な実装でなければなりません。
私の目標は、以前に描画した正方形に応じて、さまざまな位置と回転で画面に正方形を再帰的に描画する関数を作成することです。
後続の各正方形は、前の関数呼び出しよりも小さく、左に45度(前の正方形の左隅から)または前の正方形の右に45度回転する必要があります。
新しいマス目ごとに、さらに2つのマス目などが生成されます。
私の考えは、正方形の左上の点と右上の点を2つの異なる再帰関数呼び出しに渡し、これらの点を後続の正方形の開始点として使用することです。
生成された正方形は、左上隅と右上隅を再帰関数呼び出しなどにも渡します。
私が開発したコードは、再帰関数呼び出しから生成されたはずの両方の正方形を表示していません。片側のみが表示されています。
私は次のコードを開発しました(私のコードを許してください..私はC ++でコーディングしていないのが長すぎます..)
プログラムのドライバー(main.cpp)
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include "PTree.hpp"
using namespace std;
using namespace sf;
int main( int argc, char* argv[ ] )
{
double L = 0.0; // Length of square sides
int N = 0; // Number of times to call recursive function
L = atol( argv[ 1 ] );
N = atoi( argv[ 2 ] );
Vector2f vPoint;
vPoint.x = 0;
vPoint.y = 0;
// Create and Display Window
PTree tree( L, N );
return 0;
}
(PTree.hpp)
#ifndef PTREE_H
#define PTREE_H
using namespace std;
using namespace sf;
class PTree /*:public sf::Drawable, public sf::Transformable*/{
public:
// Constructor
PTree( double L, int N );
// Destructor
~PTree();
// Recursive function to draw Pythagorias Tree
void pTree( double L, int N, Vector2f vPoint, Vector2f vOrigin, float rotation );
private:
float width = 0;
float height = 0;
int originX = 0;
int originY = 0;
float rotation = 0;
RenderWindow window;
int angle1 = 0;
int angle2 = 0;
};
#endif // PTREE_H included
(PTree.cpp)
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <math.h>
#include "PTree.hpp"
#include <iostream>
using namespace std;
using namespace sf;
// Constructor
PTree::PTree( double L, int N )
{
width = ( 6 * L );
height = ( 4 * L );
Vector2f vPoint = { width/2, height - 1 };
Vector2f vOrigin;
vOrigin.x = L/2;
vOrigin.y = L;
/* vPoint.x = width/2;
vPoint.y = height - 1;
*/
window.create( VideoMode( width, height ), "Pythagoras Fractal Tree" );
pTree( L, N, vPoint, vOrigin, 0 );
}
// Destructor
PTree::~PTree(){}
/*###########################################################################*/
// Recursive function to draw Pythagorias Tree
void PTree::pTree( double L, int N, Vector2f vPoint, Vector2f vOrigin, float rotation )
{
Vector2f vPointR;
if( N < 1 )
{
return;
}
// Define a convex shape called convexSquare
ConvexShape convexSquare( 4 );
convexSquare.setPoint( 0, Vector2f( 0, 0 ));
convexSquare.setPoint( 1, Vector2f( 0, L ));
convexSquare.setPoint( 2, Vector2f( L, L ));
convexSquare.setPoint( 3, Vector2f( L, 0 ));
convexSquare.setOutlineThickness( 1.f );
convexSquare.setFillColor( Color::Black );
convexSquare.setOutlineColor( Color::White );
convexSquare.setPosition( vPoint );
convexSquare.setOrigin( vOrigin );
convexSquare.setRotation( rotation );
while( window.isOpen( ))
{
Event event;
while( window.pollEvent( event ))
{
if( event.type == Event::Closed )
{
window.close( );
}
}
if( N >= 0 )
{
window.draw( convexSquare );
window.display( );
L = ( L * ( sqrt(2)/2 ));
N = N - 1;
rotation = rotation - 135;
cout << "LOOPS:" << N << endl;
//left
vPoint = convexSquare.getTransform( ).transformPoint( convexSquare.getPoint( 0 ));
vOrigin = convexSquare.getPoint( (angle1) );
pTree( L, N, vPoint, vOrigin, rotation );
angle1 = (( angle1 + 1 ) % 4 );
//right
vPointR = convexSquare.getTransform( ).transformPoint( convexSquare.getPoint( 3 ));
vOrigin = convexSquare.getPoint( 2 );
pTree( L, N, vPointR, vOrigin, rotation-90 );
}
}
cout << "X value =" << vPoint.x << " Y value = " << vPoint.y << endl;
これまで、関数pTreeへの2回目の再帰呼び出しのために、凸形状のさまざまなポイントを返そうとしました。これも何も表示されませんでした。
当初、私はVector2f vPointのみを使用し、各再帰呼び出しの前にそれを変更していましたが、ソリューションの知識ベースを使い果たした後、Vector2fvPointRと呼ばれる右側の正方形専用の新しい変数を作成しました。
SFMLのドキュメントには、私のような初心者向けの十分な例が記載されていません。APIは基本的にオプションのリストであり、関数ごとに最小限の例があります。間違ったポイントを通過していないかどうかを確認するためにインターネットを最大限に検索しましたが、答えを見つけることができませんでした。
うまくいったことの1つは(完全には正しくありませんが)再帰呼び出しを切り替えたときでした...つまり、左側の正方形の呼び出しの前に右側の正方形の呼び出しを移動しましたが、これの問題は左側がsquaresは表示されませんでした。
この時点で、私は各正方形の適切な回転を計算しようとしていますが、これは私の問題の中で最も少ないものです。
これらの正方形を再帰的に表示しようとしている方法に問題はありますか?
StackOverflow以外のどこに行けばいいのかわかりません。
あなたの時間と専門知識をありがとう。
while
ループ全体を再帰的に呼び出さないでください。描画部分のみを再帰的に呼び出す
// Initialize window...
while (window.isOpen())
{
sf::Event event;
// Handle events...
window.clear();
// call the recursive function here
window.display();
}
また、sf::RectangleShape
代わりに描画に使用することもできますsf::ConvexShape
これが実際の「例」です。
#include <SFML/Graphics.hpp>
#include <cmath>
void drawPythagoreanTree(sf::RenderTarget&, const float, const int);
int main()
{
const float L = 150;
const int N = 14;
const unsigned width = static_cast<unsigned>(6 * L);
const unsigned height = static_cast<unsigned>(4 * L);
sf::RenderWindow window{{width, height}, "Pythagorean Tree"};
while (window.isOpen())
{
for (sf::Event event; window.pollEvent(event);)
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear(sf::Color::White);
drawPythagoreanTree(window, L, N);
window.display();
}
}
void drawPythagoreanTree(sf::RenderTarget& target, const int N,
const sf::RectangleShape& parent)
{
static const float halfSqrt2 = sqrt(2.f) / 2;
if (N < 1) return;
target.draw(parent);
auto const& sz = parent.getSize();
auto const& tf = parent.getTransform();
auto childL = parent; // copy parent's color and rotation
childL.setSize(sz * halfSqrt2); // resize
childL.setOrigin(0, childL.getSize().y); // bottom left corner
childL.setPosition(tf.transformPoint({0, 0})); // reposition
childL.rotate(-45);
drawPythagoreanTree(target, N - 1, childL);
auto childR = parent; // copy parent's color and rotation
childR.setSize(sz * halfSqrt2); // resize
childR.setOrigin(childR.getSize()); // bottom right corner
childR.setPosition(tf.transformPoint({sz.x, 0})); // reposition
childR.rotate(45);
drawPythagoreanTree(target, N - 1, childR);
}
void drawPythagoreanTree(sf::RenderTarget& target, const float L, const int N)
{
sf::RectangleShape rect{{L, L}};
// set origin to center of the rect, easier to center position on screen
rect.setOrigin(rect.getSize() / 2.f);
rect.setPosition(target.getSize().x / 2.f, target.getSize().y - L / 2.f);
rect.setFillColor(sf::Color::Black);
drawPythagoreanTree(target, N, rect);
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加