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?
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ę.
Sumek chcesz rysowac fraktale?
Sumek napisał(a)
W windows Forms chyba się nie da rekurencyjnie pisać.
Następna perełka...
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
}
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
Rozumiem. A gdybym chciał to zrobić nie w Windows Forms lecz w konsoli? To jaką funkcją zainicjować tryb graficzny w konsoli?
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
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);
}
}
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.
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);
}
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
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:
- Jak wyznaczyć z funkcji środek okna oraz żeby się dynamicznie ustawiał wraz ze zmianą wielkości okna?
- Oraz jak ustawić rozmiar okna np. 500 x 500 pisząc kodem?
Sumek napisał(a)
- Oraz jak ustawić rozmiar okna np. 500 x 500 pisząc kodem?
this.Size = new Size(500, 500);