Rekurencyjne rysowanie odcinków.

0

Witam.
Jak można rekurencyjnie narysować odcinki? W windows Forms chyba się nie da rekurencyjnie pisać. A w Console Application nie da się rysować. Ma ktoś jakieś pomysły?

0

Da się rysować w konsoli, da się pisać rekurencyjnie w WinForms.
Określ dokładnie co masz na myśli mówiąc rysować rekurencyjnie odcinki bo jakoś nie jarzę.

0

Sumek chcesz rysowac fraktale?

0
Sumek napisał(a)

W windows Forms chyba się nie da rekurencyjnie pisać.

Następna perełka...

0

massther to jeszcze nie ten poziom bym je rysował.
Mam program w C++ i chcę go przerobić na C#.

 const double alpha = 10;

void spirala(double lg, double x, double y)
{
	if (lg > 0)
	{
		lineto(x + lg, y);
		lineto(x + lg, y + lg);
		lineto(x + alpha, y + lg);
		lineto(x + alpha, y + alpha);
		spirala(lg - 2 * alpha, x + alpha, y + alpha);
	}
}

int main()
{
	//tu zainicjuj tryb graficzny
	moveto(90, 50);
	spirala(getmaxx()/2, getx(), gety());
	getch();
	//tu zamknij tryb graficzny
} 
0

no ale gdzie tu problem?
generalnie rekurencja to odwolanie sie funkcji do samej siebie, czyli w ciele funkcji jest wywolanie jej samej z jakimis innymi paramtrami
właściwie rekurencję można uzyskać chyba w każdym języku programowania - pisze chyba, bo oczywiście wszystkich nie znam, ale nie widzę teoretycznych przeszkód, musiałoby istnieć w specyfikacji języka, że w funkcji nie może być odwołania do niej samej
przerobienie tego na c# np. win forms to banal
musisz tylko napisac odpowiednie funkcje: getmaxx(), getx(), gety(), moveto(x,y), lineto(x,y)
natomast sama funkcja spirala nie wymaga zmian

0

Rozumiem. A gdybym chciał to zrobić nie w Windows Forms lecz w konsoli? To jaką funkcją zainicjować tryb graficzny w konsoli?

0

w konsoli nie można rysować w takim sensie jak w winForms, możesz wypisywać znaki, a ustawiać pozycję kursora za pomocą metody SetCursorPosition
http://msdn.microsoft.com/en-us/library/system.console.setcursorposition.aspx
chcesz tryb raficzy i kontrolować każdy pixel, rysuj w c# na oknie lub na obrazku lub pobaw sie wpf

0

Czyli nie da się tego zrobić tak "bezpośrednio" jak w C++? Mam kod i jeżeli wstawię go pod Form1.cs to działa i rysuje poziome linie ale nie wiem jak zrobić by Program.cs z funkcją main mógł rekurencyjnie wywoływać.

 protected override void OnPaint(PaintEventArgs paintEvnt) 
{ 
    Graphics gfx = paintEvnt.Graphics; 
    Pen myPen = new Pen(Color.Black); 
    for(int i = 20; i < 250; i = i + 10) 
    { 
    gfx.DrawLine(myPen, 20, i, 270, i); 
    } 
} 
0

teoretycznie konsola tez wyswietla sie w oknie, wiec jak masz uchwyt okna używając winAPI możesz po nim dowoli rysować, ale na twoim poziomie to na razie za trudne, więc w ten temat nie brnij :)
Zacznijmy od tego czym jest OnPaint, to obsluga zdarzenia odrysowania okna, więc wywoływanie jej rekurencyjnie skończy się co najmniej źle :D
Musisz całą logikę rysowania umieścić w innej funkcji, która może wykonywać się rekurencyjnie. Następnie umieścić jej wywołanie w OnPaint. Oczywiście jeśli tylko raz coś rysujesz i nie zmienia się to w czasie, to warto narysować to na obrazku, a później w OnPaint przerysowywać obrazek na okno. Kolejna kwestia, jeśli rysowanie przez funkcję rekurencyjną trwa długo , to umieszczenie jej w OnPaint także nie skończy się dobrze, bo po prostu aplikacja się zawiesi.

1

OnPaint, to obsluga zdarzenia odrysowania okna, więc wywoływanie jej rekurencyjnie skończy się co najmniej źle

?
OnPaint to metoda wywoływana w reakcji na zajście zdarzenia odrysowania okna, wywołanie jej rekurencyjnie zupełnie nic nie zmieni.

umieszczenie jej w OnPaint także nie skończy się dobrze, bo po prostu aplikacja się zawiesi.

Rozumiem o co ci chodziło, ale nieprecyzyjnie się wyraziłeś - aplikacja się nie 'zawiesi', aplikacja będzie 'mrugać'.

Na szybko coś takiego napisałem:

        const float alpha = 10;

        private void DrawSpirala(Graphics g, PointF last, float lg, float x, float y)
        // jak jest %^*(&% spirala po angielsku bo nie chce mi się szukać...?
        {
            if (lg > 0)
            {
                PointF[] points = 
                 {
                    last,
                    new PointF(x+lg, y),
                    new PointF(x+lg, y+lg),
                    new PointF(x+alpha, y+lg),
                    new PointF(x+alpha, y+alpha),
                };
                g.DrawLines(Pens.Blue, points);

                DrawSpirala(g, new PointF(x + alpha, y + alpha), lg - 2 * alpha, x + alpha, y + alpha);
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            DrawSpirala(g, new PointF(90, 50), /*?*/, /*?*/, /*?*/); // co te funkcje mają robić?

            base.OnPaint(e);
        }
0
MSM napisał(a)

OnPaint, to obsluga zdarzenia odrysowania okna, więc wywoływanie jej rekurencyjnie skończy się co najmniej źle

?
OnPaint to metoda wywoływana w reakcji na zajście zdarzenia odrysowania okna, wywołanie jej rekurencyjnie zupełnie nic nie zmieni.

hmmm, jesteś pewien że nic nie zmieni? zależy jak długo będzie trwało (kwestia z cześci drugiej)
i pozostaje kwestia przekazania jakiegos parametru (-ów) dla których ta rekurencja ma się wykonywać oraz warunku stopu, niby można przez pola prywatne to zrobić

MSM napisał(a)

umieszczenie jej w OnPaint także nie skończy się dobrze, bo po prostu aplikacja się zawiesi.

Rozumiem o co ci chodziło, ale nieprecyzyjnie się wyraziłeś - aplikacja się nie 'zawiesi', aplikacja będzie 'mrugać'.

i znowu nie, bo jęśli odrysowywanie będzie trwało długo to zablokuje obsługę innych komunikatów napływających do okna, czyli próba np. przeciągnięcia tego okna skończy się wysłaniem kolejnego komunikatu o odrysowanie, kiedy jeszcze pierwsze się nie zakończyło, wg mnie zwis murowany, ale jak twierdzisz inaczej, to wieczorem wyprodukuje przykładowy program

0

Działający kod programu wygląda tak:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Formx
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        const float alpha = 10;
        private void Spiral(Graphics g, PointF last, float lg, float x, float y)
        {
            if (lg > 0)
            {
                PointF[] points = 
                {
                    last, 
                    new PointF(x + lg, y),
                    new PointF(x + lg, y + lg),
                    new PointF(x + alpha, y + lg),
                    new PointF(x + alpha, y + alpha),
                };
                g.DrawLines(Pens.Black, points);
                Spiral(g, new PointF(x + alpha, y + alpha), lg - 2 * alpha, x + alpha, y + alpha);
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            float lg = 200;
            Spiral(g, new PointF(10, 10), lg, 10, 10);
            Console.Read();
        }
    }
}

Mam takie dwa kosmetyczne pytania:

  1. Jak wyznaczyć z funkcji środek okna oraz żeby się dynamicznie ustawiał wraz ze zmianą wielkości okna?
  2. Oraz jak ustawić rozmiar okna np. 500 x 500 pisząc kodem?
0
Sumek napisał(a)
  1. Oraz jak ustawić rozmiar okna np. 500 x 500 pisząc kodem?
this.Size = new Size(500, 500);

1 użytkowników online, w tym zalogowanych: 0, gości: 1