| |
VB.NET - FortgeschritteneRe: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 25.02.07 10:13 |
| Hallo GPM
Inzwischen habe ich eigentlich schon alles was ich benötige, nur eine Sache macht mir noch Probleme:
In der GetPoints Sub wird ja berechnet.
Nun übergebe ich die bzp Punkte so wie am Monitor. Je kleiner die gezeigte Bezier, desto ungenauer die Berechnungen im Kommabereich.
Beispiel: 33% sind 33,3333 Pixel ... muss auf 33 abgerunden werden, was eben im Kommabereich sichtbar wird.
Meine Idee:
Ich Berechne die Punkte unabhängig der momentanen Anzeige des Bezier.
Habe da aber so meine Probleme. Dachte in der GetPoints die Koordinaten *1000 zu rechnen ... in der Paint Sub der Picturebox alles noch so hoch berechnen zu lassen und beim zeichen der Punkte, die Koordinaten wieder /1000
Leider klappt das so wohl nicht. Endweder dauert die Berechnung in der GetPoints ewig lange oder ist eine Dauerschleife.
Mein Versuch:
Sub GetPoints()
Dim r As RectangleF
plist.Clear()
gp.Reset()
Dim a, b, c, d As PointF
a.X = bzp(0).X * 1000
a.Y = bzp(0).Y * 1000
b.X = bzp(1).X * 1000
b.Y = bzp(1).Y * 1000
c.X = bzp(2).X * 1000
c.Y = bzp(2).Y * 1000
d.X = bzp(3).X * 1000
d.Y = bzp(3).Y * 1000
gp.AddBezier(a, b, c, d)
r.Location = a
Do
plist.Add(r)
Select Case True
Case gp.IsOutlineVisible(r.X + 1, r.Y - 1, Pens.Black)
r.X += 1
r.Y -= 1
r.Width += 1414
Case gp.IsOutlineVisible(r.X, r.Y - 1, Pens.Black)
r.Y -= 1
r.Width += 1000
Case gp.IsOutlineVisible(r.X + 1, r.Y, Pens.Black)
r.X += 1
r.Width += 1000
Case gp.IsOutlineVisible(r.X + 1, r.Y + 1, Pens.Black)
r.X += 1
r.Y -= 1
r.Width += 1414
Case Else
Exit Do
End Select
r.Height = (400 - (r.Y - 50)) / 0.4
Loop
End Sub Hier erfolgt wohl(?) eine Endlosschleife.
Was wäre, wenn ich für die Berechnung FEST eine Größe hernehme und für die Anzeige diese Ableite.
Problem sehe ich da bei den Zwischenpunkte. Diese werden ja mit der Maus verschoben. Also müßte ich die koordinaten passend zur Festen Berechnung skalieren. Nicht so das wahre, oder?
Was würdest du vorschlagen?
Ich möchte gerne die Zwischenpunkte als Prozent haben (ist eh schon), aber auf 2 Kommastellen genau. Wenn ich ihn die Debug Ausgabe blicke, ist bei 2 Mittelwerten (33% und 66%) als PointF ein Kommawert zu sehen ... dieser wird bei Pixel ja gerundet.
Wie geschrieben, würde gerne die Berechnung unabhängig der Anzeige vornehmen (bzp(0) = 0,0;bzp(3)=1000,1000)
Nur die Zwischenpunkte dann passend umzurechnen??
Danke dir
Hannes
PS: Werde den Code dann hier posten, aber je nach Größe meiner Form erhalte ich statt 100% nur 99,8684738%. Konnte hier den Fehler noch nicht finden | |
Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 24.12.06 10:44 |
| Hallo
Ich möchte eine Berechnung machen, was mir eine Art Fade-out ,Fade-In Funktion nachstellt.
Beispiel:
a=0, b=100
Nun soll in 10er einheiten der Fade beginnen 0,10,20,30,...
Aber ich möchte diesen nicht linear, sonder mittels einer Kurve zeigen, die man mit der Maus biegen kann.
Auch möchte keine Überblendungen machen, sondern nur die Ergebnisse verarbeiten.
Hat da jemand eine Idee,wie ich das machen könnte?
In PlanetSource und CodeProject habe ich schon gesucht, aber nur lineare gefunden.
Im weiteren Ausbau, soll dann noch eine Umrechnung stattfinden:
a=4,b=20
a1=0,b1=1000
Zwischenwerte werden dann immer als a1-b1 ausgegeben, wobei als Basis a-b gewählt ist.
Beispiel:
a=0,b=100
a1=100,b1=200
c(50) = 150
Und so möchte ich dann mittels der Kurve die Zwischenwerte dementsprechend ausrechnen lassen.
Anhand der Biegung ist dann c(50) als Beispiel 130.
Nur wie zeichne ich so eine Kurve? In einer Picturebox mittels Line ist eine gerade kein Problem, aber eine Kurve, die ich auch mit der Maus biegen kann???
Und anhand dieser Kurve sollen dann die Zwischenergebnisse berechnet werden. Also soll die Kurve der Pfad sein.
Bei Grafikprogrammen sieht man das häufig.
Programmiere selbst aber nur ein kleines Tool
Und da wäre ich für Hilfe dankbar
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 24.12.06 19:43 |
| Schau Dir mal die Demo einer einfachen Bezierkurve mit 4 Punkten an.
Mit der rechten Maustaste werden die 4 Punkte ein- und ausgeblendet.
Eventuell hilft Dir das schon etwas.
Imports System.Drawing.Drawing2D
Public Class Form1
Dim bzpoints() As Point = {New Point(50, 400), New Point(250, 400), New _
Point(400, 400), New Point(450, 100)}
Dim gpath As New GraphicsPath
Dim curpoint As Int32
Dim ptsvisible As Boolean
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
curpoint = -1
If ptsvisible AndAlso gpath.IsVisible(e.Location) Then
For i As Int32 = 0 To 3
If Math.Abs(e.X - bzpoints(i).X) < 6 AndAlso Math.Abs(e.Y - _
bzpoints(i).Y) < 6 Then
curpoint = i
End If
Next
End If
If e.Button = Windows.Forms.MouseButtons.Right Then
ptsvisible = Not ptsvisible
Me.Refresh()
End If
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.DrawBezier(New Pen(Color.Yellow, 2), bzpoints(0), bzpoints( _
1), bzpoints(2), bzpoints(3))
If ptsvisible Then
gpath.Reset()
For i As Int32 = 0 To 3
gpath.AddEllipse(bzpoints(i).X - 5, bzpoints(i).Y - 5, 10, 10)
Next
e.Graphics.FillPath(Brushes.Red, gpath)
End If
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint Or _
ControlStyles.AllPaintingInWmPaint, True)
Me.SetBounds(100, 100, 500, 500)
Me.BackColor = Color.Black
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If ptsvisible AndAlso curpoint > -1 AndAlso e.Button = _
Windows.Forms.MouseButtons.Left Then
bzpoints(curpoint) = New Point(e.X, e.Y)
Me.Refresh()
End If
End Sub
End Class MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 24.12.06 20:03 |
| Hallo GPM
Oh, vielen Dank ... werde ich in den nächsten Tagen testen.
Dann gilt es nur mehr, die Berechnungen von Anfang und Ende der Bezierkurve anzupassen.
Wünsche dir frohe Weihnachten ... Klasse für die schnelle Reaktion am 24.12 !!
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 25.12.06 09:47 |
| Hallo GPM
Habe deinen Code nun getestet.
Absolut klasse !! Vielen Dank für dein Weihnachtsgeschenk
Nun müßte ich aber noch etwas nachhacken, wenn du erlaubst:
Kann ich die Spline automatisch reseten, damit es eine Gerade von Anfang zu Ende ergibt.
Die zwei mittleren Punkte müßten genau auf der Linie plaziert werden, damit es eine gerade ergibt.
Kann ich das auch irgendwie zuweisen?
Noch eine freche Frage:
Wie würdest du es am besten machen, wenn ich nun anhand dieser Kurve die Werte ausgeben möchte?
Beispiel:
Links unten = 0
Rechts oben = 100
10 Zwischenschritte.
Wäre es eine gerade Linie, würde das ergebniss:
0
10
20
30
40
50
60
70
80
90
100
ergeben
Biege ich aber die Kurve beim ersten Punkt nach unten, wäre das Ergebniss ungefähr:
0
2,5
5
10
15
22
30
42
60
80
100
also gegen Ende zu, wäre der Abstand größer, da die Kurve steiler wird.
Kann ich das anhand deiner Kurve errechnen?
Vielen Dank für deine Hilfe
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 25.12.06 10:25 |
| Hannes H. schrieb:
Zitat: | |
Kann ich die Spline automatisch reseten, damit es eine Gerade
von Anfang zu Ende ergibt.
Die zwei mittleren Punkte müßten genau auf der Linie plaziert
werden, damit es eine gerade ergibt.
Kann ich das auch irgendwie zuweisen?
| |
Sorry für die dumme Frage ... habe da zu kompliziert mit Spline und Ellipse gedacht
Die Punkte auf eine Diagonale zu legen ist ja kein Problem!
Die zweite Frage ist aber noch aktuell.
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 25.12.06 14:39 |
| Mal im Internet nach Bezierkurve suchen.
Hier schon mal eine Seite:
http://www.ullala.at/experiments/movement/bew_bez.html MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 25.12.06 16:16 |
| Hallo GPM
Danke für den Link.
Nur wie rechne ich mit 2 Koordinaten Punkte?
Als Formel für C:
3*(P1-P0)
P1 und P0 sind ja Koordinaten, oder?
Wie kann ich diese subtrahieren? Einfach x und y jeweils subtrahieren?
Diese Werte dann * 3 ?
Dann hätte ich wieder eine Koordinate, welche für Pt wieder genommen wird.
Oder muss ich die Formeln jeweils für x und y getrennt rechnen und die Ergebnisse am Ende wieder als Koordinate zusammenstellen?
Danke dir
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 25.12.06 17:05 |
| Nochmals Hallo GPM
Habe nun diese Function erstellt:
Dim ay, ax, by, bx, cy, cx, pty, ptx, t As Double
CheckPoint.Clear()
For t = 0 To 1 Step 0.2
cx = 3 * (bzpoints(1).X - bzpoints(0).X)
bx = 3 * (bzpoints(2).X - bzpoints(1).X) - cx
ax = bzpoints(3).X - bzpoints(0).X - cx - bx
ptx = ax * t ^ 3 + bx * t ^ 2 + cx * t + bzpoints(0).X
cy = 3 * (bzpoints(1).Y - bzpoints(0).Y)
by = 3 * (bzpoints(2).Y - bzpoints(1).Y) - cy
ay = bzpoints(3).Y - bzpoints(0).Y - cy - by
pty = ay * t ^ 3 + by * t ^ 2 + cy * t + bzpoints(0).Y
CheckPoint.Add(New Point(ptx, pty))
Next
Refresh() Jedoch werden mir das die Punkte nicht gleichmäßig aufgeteilt.
Ich bräuchte auf der geraden X Achse 5 gleich große (in der Xachse gesehen) Abstände.
Die obige Function ist abhängig wie die Kontrollknoten gezogen sind. Ziehe ich die weit, ist der Abstand am Anfang größer.
Hast du da noch einen Tipp?
Oder muss ich das verschieben der Kontrollpunkte einschränken, damit aus der X-Achse gesehen ein gleicher Abstand bekomme?
Danke
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 25.12.06 18:48 |
| Da scheint etwas nicht zu stimmen.
Probiere es mal mit dieser Funktion :
Function BezierPos(ByVal t As Double) As Point
Dim p As Point
p.X = bzpoints(0).X * t ^ 3 + bzpoints(1).X * 3 * t ^ 2 * (1 - t) + bzpoints( _
2).X * 3 * t * (1 - t) ^ 2 + bzpoints(3).X * (1 - t) ^ 3
p.Y = bzpoints(0).Y * t ^ 3 + bzpoints(1).Y * 3 * t ^ 2 * (1 - t) + bzpoints( _
2).Y * 3 * t * (1 - t) ^ 2 + bzpoints(3).Y * (1 - t) ^ 3
Return p
End Function MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 25.12.06 18:57 |
| Hier noch das Tutorial aus dem ich die Funktion habe:
http://www.codeworx.org/opengl_tut28.php MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 26.12.06 09:41 |
| Hallo GPM
Auch mit deiner Function habe ich das Problem.
Eventuell ist das ja so und ich bräuchte eine andere.
Aber nochmal zum verdeutlichen:
Eine gerade, die Kontrollpunkte sind auf der geraden gleichmäßig aufgeteilt:
http://www.eisbaer-manager.de/downloads/Screen1.gif
Ziehe ich nun die 2 Kontrollpunkte mit der Maus, und berechne wieder, ist der Abstand zwischen den Punkten nicht gleichmäßig:
http://www.eisbaer-manager.de/downloads/Screen2.gif
Ich berechne die Punkte mittels deine Function in einer Schleife (For t = 0 to 1 step 0.2)
Daraus schließe ich, das die Strecke 0 - 1 für t zwar Anfang - Ende der Bezierkurve ist, jedoch diese nicht gleichmäßig diese Darstellt.
Je weiter ich den Kontrollpunkt 1 vom Anfang wegziehe, umso weiter wird dieser Abstand.
Hier nochmal mein Code:
Dim bzpoints() As Point = {New Point(50, 400), New Point(250, 400), New _
Point(400, 400), New Point(450, 100)}
Dim CheckPoint As New ArrayList
Dim gpath As New GraphicsPath
Dim curpoint As Int32
Dim ptsvisible As Boolean
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
curpoint = -1
If ptsvisible AndAlso gpath.IsVisible(New Point(e.X, e.Y)) Then
For i As Int32 = 1 To 2
If Math.Abs(e.X - bzpoints(i).X) < 6 AndAlso Math.Abs(e.Y - _
bzpoints(i).Y) < 6 Then
curpoint = i
End If
Next
End If
If e.Button = Windows.Forms.MouseButtons.Right Then
ptsvisible = Not ptsvisible
Me.Refresh()
End If
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
For Each h As Point In CheckPoint
e.Graphics.DrawPie(Pens.Green, h.X - 5, h.Y - 5, 10, 10, 0, 360)
Next
e.Graphics.DrawBezier(New Pen(Color.Yellow, 2), bzpoints(0), bzpoints( _
1), bzpoints(2), bzpoints(3))
If ptsvisible Then
gpath.Reset()
For i As Int32 = 0 To 3
gpath.AddEllipse(bzpoints(i).X - 5, bzpoints(i).Y - 5, 10, 10)
Next
e.Graphics.FillPath(Brushes.Red, gpath)
End If
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
CheckPoint.Add(New Point(0, 0))
Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint Or _
ControlStyles.AllPaintingInWmPaint, True)
Me.SetBounds(100, 100, 500, 500)
Me.BackColor = Color.Black
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
If ptsvisible AndAlso curpoint > -1 AndAlso e.Button = _
Windows.Forms.MouseButtons.Left Then
bzpoints(curpoint) = New Point(e.X, e.Y)
Me.Refresh()
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button1.Click
bzpoints(0) = New Point(100, 400)
bzpoints(1) = New Point(200, 300)
bzpoints(2) = New Point(300, 200)
bzpoints(3) = New Point(400, 100)
Refresh()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button2.Click
Dim ay, ax, by, bx, cy, cx, pty, ptx, t As Double
CheckPoint.Clear()
For t = 0 To 1 Step 0.2
CheckPoint.Add(BezierPos(t))
Next
Refresh()
End Sub
Function BezierPos(ByVal t As Double) As Point
Dim p As Point
p.X = bzpoints(0).X * t ^ 3 + bzpoints(1).X * 3 * t ^ 2 * (1 - t) + _
bzpoints(2).X * 3 * t * (1 - t) ^ 2 + bzpoints(3).X * (1 - t) ^ 3
p.Y = bzpoints(0).Y * t ^ 3 + bzpoints(1).Y * 3 * t ^ 2 * (1 - t) + _
bzpoints(2).Y * 3 * t * (1 - t) ^ 2 + bzpoints(3).Y * (1 - t) ^ 3
Return p
End Function | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 26.12.06 11:34 |
| Hallo Hannes
Ich hatte das selber nicht ausprobiert.
Die Funktionen werden scheinbar nur zur Berechnung von Flugkurven bei DirectX-Sprites
eingesetzt. Für lineare Abstände auf der X-Achse sind diese wohl nicht geeignet.
Ich habe sowas auch noch nicht gebraucht.
Entweder versuchen soeine Funktion selber hinzubekommen oder brutal den ganzen
Kurvenverlauf von p(0) bis P(3) mit einem kleinen t-Schritt durchlaufen.
Wird nun die gesuchte X-Position erreicht gibt man den dazugehörenden Y-Wert zurück.
MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 26.12.06 13:52 |
| Hier mal durch Testen des X-Wertes:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button2.Click
GetPoints()
End Sub
Sub GetPoints()
CheckPoint.Clear()
Dim x As Int32
Dim p As Point
For t As Double = 0.1 To 0.9 Step 0.1
x = bzpoints(0).X + t * (bzpoints(3).X - bzpoints(0).X)
For i As Double = 1 To 0 Step -0.001
p.X = bzpoints(0).X * i ^ 3 + bzpoints(1).X * 3 * i ^ 2 * (1 - _
i) + bzpoints(2).X * 3 * i * (1 - i) ^ 2 + bzpoints(3).X * (1 _
- i) ^ 3
p.Y = bzpoints(0).Y * i ^ 3 + bzpoints(1).Y * 3 * i ^ 2 * (1 - _
i) + bzpoints(2).Y * 3 * i * (1 - i) ^ 2 + bzpoints(3).Y * (1 - _
i) ^ 3
If p.X >= x Then
CheckPoint.Add(p)
Exit For
End If
Next
Next
Refresh()
End Sub MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 26.12.06 16:18 |
| Hallo GPM
Supi, das hilft schon einmal weiter. Danke.
Eine zusätzliche Einteilung über die Länge der Bezierkurve ist wohl nicht so ohne möglich?
Wäre klasse wenn man auch auf die Länge der Bezierkurve eine einheitliche Teilung bekommen würde. Aber da funktioniert dies ja nicht, oder?
So hilft es aber schon einmal weiter!
Danke
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 30.12.06 09:02 |
| Hallo GPM
Sag mal, würde das ganze auch mittels DrawCurve funktionieren?
Könnte man da entlang der Kurve ein gleichmäßige Teilung berechnen?
Danke
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 30.12.06 09:59 |
| Eine Kurve beinhaltet sogar zwei Bezierkurven. Schau Dir das mal in der Demo an.
Über die rechte Maustaste siehst Du die Teilstücke.
Imports System.Drawing.Drawing2D
Public Class Form1
Dim pt() As Point = {New Point(100, 400), New Point(250, 250), New Point( _
400, 100)}
Dim gp, gpath As New GraphicsPath
Dim curpoint As Int32
Dim ptsvisible As Boolean = True
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
curpoint = -1
If ptsvisible AndAlso gpath.IsVisible(e.Location) Then
For i As Int32 = 0 To 2
If Math.Abs(e.X - pt(i).X) < 6 AndAlso Math.Abs(e.Y - pt(i).Y) _
< 6 Then
curpoint = i
End If
Next
End If
If e.Button = Windows.Forms.MouseButtons.Right Then
ptsvisible = Not ptsvisible
Me.Refresh()
End If
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
If ptsvisible Then
e.Graphics.DrawCurve(New Pen(Color.Yellow, 2), pt)
gpath.Reset()
For i As Int32 = 0 To 2
gpath.AddEllipse(pt(i).X - 5, pt(i).Y - 5, 10, 10)
Next
e.Graphics.FillPath(Brushes.Red, gpath)
Else
Dim plist As New List(Of PointF)
gp.Reset()
gp.AddCurve(pt)
plist.AddRange(gp.PathPoints)
e.Graphics.DrawBezier(New Pen(Color.Red, 2), plist(0), plist(1), _
plist(2), plist(3))
e.Graphics.DrawBezier(New Pen(Color.Blue, 2), plist(3), plist(4), _
plist(5), plist(6))
For Each p As PointF In gp.PathPoints
e.Graphics.FillEllipse(Brushes.Green, p.X - 4, p.Y - 4, 8, 8)
Next
End If
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
Me.Text = "Demo Kurve"
Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint Or _
ControlStyles.AllPaintingInWmPaint, True)
Me.SetBounds(100, 100, 500, 500)
Me.BackColor = Color.Black
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If ptsvisible AndAlso curpoint > -1 AndAlso e.Button = _
Windows.Forms.MouseButtons.Left Then
pt(curpoint) = New Point(e.X, e.Y)
Me.Refresh()
End If
End Sub
End Class MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 30.12.06 11:19 |
| Du kannst aber auch zu jedem X-Punkt der Kurve/Bezierkurve den Y-Wert ausmessen
statt zu berechnen. Hier wurde diese Technik verwendet.
http://www.vbarchiv.net/forum/id10_i53423t53423.html MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 30.12.06 16:00 |
| Hallo GPM
Danke für deine Hilfe.
Nun, die Berechnung muss im Hintergrund erfolgen, daher wird das Ausmessen wohl nicht möglich sein, da die Grafik nicht gezeigt werden soll.
Es soll die Biegung grafisch festgelegt werden. Diese soll dann gespeichert werden.
Wenn es nun einen Wert zu umrechnen gilt, soll anhand der gespecheicherten Kurve dies geschehen.
Ich dachte dabei die Y Achse auszurechnen. Nämlich wie weit diese beim Wert X von der geraden abweicht und dann die Ausgabe darauf basierend anzugleichen.
Für dein Beispiel mit der Umrechnung, müßen ja die Pixel gezeichnet werden, oder?
Das mit dem testen auf der X Achse ist schon einmal ein Anfang, super wäre es eben wenn die Länge der Bezierkurve als Basis genommen wird und diese in X Teile zu zerlegen.
Dann bei dem Teil prüfen, wie weit von der geraden weg ist und so in % die Abweichung auf den realen Wert übertragen.
So dachte ich mir das eben ... falls da keine Lösung in Sicht ist, muss ich eben die Werte an der X Achse durchprüfen.
Danke
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 30.12.06 17:29 |
| 1. Nein.
Die sichtbare Kurve wird nicht ausgemessen sondern die unsichtbare Kurve im Path.
Ob Du die Kurve aus dem Path anzeigst oder nicht ist unwichtig.
2.
In der Sub GetPoints ist die Länge der Bezierkurve doch immer = 100%
Die t -Punkte sind hier bei 10 - 90% ( step 10% ) der Gesamtlänge der Kurve
Somit kann man doch den Abstand von der Grundlinie( bzpoint(0).Y) zum Y-Wert
der Kurve bei den gewünschten Prozentwerten ausrechnen.
For t As Double = 0.1 To 0.9 Step 0.1 ' Test bei (t * 100) % der
' Gesamtlänge der Kurve
x = bzpoints(0).X + t * (bzpoints(3).X - bzpoints(0).X) MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 30.12.06 18:37 |
| Hallo GPM
zu 2)
Habs jetzt mit dem neuen Code nicht getestet, aber bei den Bezierkurven ist ja folgendes Problem (wie vorhin schon geschildert):
Kurve = 100%
Kurvenlänge als Beispiel 100cm
Dann ist bei 10% nicht 10cm ... sondern hängt ab, wie die Kontrollpunkte angeordnet sind.
siehe mein Posting mit den 2 Links zu den Bildern.
Werde das aber noch weiter verfolgen
Danke
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 03.01.07 13:35 |
| Hallo Hannes
Hier wird die Kuvenlänge linear aufgeteilt.
Die Zahl der Abschnitte ist einstellbar.
Die Punktwerte sind in % der Kurvenhöhe angegeben.
Für die Berechnung braucht die Bezierkurve nicht auf dem Bildschirm angezeigt werden.
Die Berechnung wird über die Pixel im GraphicsPath gemacht.
Imports System.Drawing.Drawing2D
Public Class Form1
Dim bzp() As Point = {New Point(50, 450), New Point(100, 400), New Point( _
400, 100), New Point(450, 50)}
Dim gp, gpath As New GraphicsPath
Dim plist As New List(Of RectangleF)
Dim ts As Int32 = 10 ' Anzahl der Abschnitte
Dim curpoint As Int32
Dim ptsvisible As Boolean
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
curpoint = -1
If ptsvisible AndAlso gpath.IsVisible(e.Location) Then
For i As Int32 = 1 To 2
If Math.Abs(e.X - bzp(i).X) < 6 AndAlso Math.Abs(e.Y - bzp( _
i).Y) < 6 Then
curpoint = i
End If
Next
End If
If e.Button = Windows.Forms.MouseButtons.Right Then
ptsvisible = Not ptsvisible
If Not ptsvisible Then
GetPoints()
End If
Me.Refresh()
End If
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.DrawRectangle(Pens.DimGray, 50, 50, 400, 400)
e.Graphics.DrawBezier(New Pen(Color.Yellow, 2), bzp(0), bzp(1), bzp(2), _
bzp(3))
If ptsvisible Then
gpath.Reset()
For i As Int32 = 0 To 3
gpath.AddEllipse(bzp(i).X - 5, bzp(i).Y - 5, 10, 10)
Next
e.Graphics.FillPath(Brushes.Red, gpath)
Else
Dim max As Int32 = plist(plist.Count - 1).Width
Dim ppos As Int32 = 50
For i As Int32 = 1 To ts - 1
For Each r As RectangleF In plist
If r.Width >= i * max \ ts Then
e.Graphics.FillEllipse(Brushes.Red, r.X - 5, r.Y - 5, _
10, 10)
e.Graphics.DrawString((r.Height / 10).ToString(Format( _
"f2")) & " %", Me.Font, Brushes.Yellow, 2, ppos)
ppos += 15
Exit For
End If
Next
Next
End If
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint Or _
ControlStyles.AllPaintingInWmPaint, True)
Me.SetBounds(100, 100, 510, 520)
Me.BackColor = Color.Black
Me.Text = "Bezierkurve mit linearer Aufteilung der Länge"
GetPoints()
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If ptsvisible AndAlso curpoint > -1 AndAlso e.Button = _
Windows.Forms.MouseButtons.Left Then
If e.X >= 50 AndAlso e.X <= 450 AndAlso e.Y >= 50 AndAlso e.Y _
<= 450 Then
bzp(curpoint) = New Point(e.X, e.Y)
Me.Refresh()
End If
End If
End Sub
Sub GetPoints()
Dim r As RectangleF
r.Location = bzp(0)
plist.Clear()
gp.Reset()
gp.AddBezier(bzp(0), bzp(1), bzp(2), bzp(3))
Do
plist.Add(r)
Select Case True
Case gp.IsOutlineVisible(r.X + 1, r.Y - 1, Pens.Black)
r.X += 1
r.Y -= 1
r.Width += 1414
Case gp.IsOutlineVisible(r.X, r.Y - 1, Pens.Black)
r.Y -= 1
r.Width += 1000
Case gp.IsOutlineVisible(r.X + 1, r.Y, Pens.Black)
r.X += 1
r.Width += 1000
Case gp.IsOutlineVisible(r.X + 1, r.Y + 1, Pens.Black)
r.X += 1
r.Y -= 1
r.Width += 1414
Case Else
Exit Do
End Select
r.Height = (400 - (r.Y - 50)) / 0.4
Loop
End Sub MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 25.01.07 21:07 |
| Hallo GPM
SORRY, das ich erst jetzt wieder Zeit habe, mich dem Thema zu widmen.
Dein Code ist SUPER ... damit kann ich schon sehr viel anfangen.
Ich muss noch versuchen, wenn der direkte Weg (gerade) von Anfang und Ende ein Punkt bei 56% angenommen wird, wo 56% auf der Spline liegt.
Ich brauche da den Unterschied in der Y Achse um so die Abweichung zu errechnen,
Falls ich das nicht hinbekomme, melde ich mich nochmal.
Herzlichen Dank
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 20.02.07 10:40 |
| Hallo GPM
Habe nun wiede einmal an diesem Projekt weitergearbeitet ... habe es auf meine Bedürfnisse abgeändert ... funktioniert auch soweit.
Habe aber eine Frage:
Wie könnt ich den Y Wert des Punktes auf der Länge von 33 Prozent herausbekommen?
Es wird ja in einer Schleife hochgerechnet ... wenn ich theoretisch 3 Mittelpunkte setzen würde, hätte ich den 1 Punkt bei 33,3 Periodisch.
Würde eine Berechnung eines einzelnen Punktes auch direkt möglich sein?
Als Beispiel 33 Prozent der Länge der Bezierkurve ... wie wäre da die Koordinaten?
Und ... um eine Berechnung hier ermöglichen zu können, muss dies über Graphis erfolgen, wo ich eben in eine Picturebox zeichen müßte.
Würde ich die Berechnung im Hintergrund durchführen ... müßte ich eine Picturebox einfach unsichtbar darstellen?
Für die Berechnung muss ja gezeichnet werden, oder?
Vielen Dank
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 20.02.07 12:16 |
| In plist(plist.Count - 1).Width steht die Gesamtlänge der Kurve
Nun brauchst Du nur die Liste nach dem Punkt zu durchsuchen wo die Länge 1/3 ist.
Dim max As Int32 = plist(plist.Count - 1).Width
For Each r As RectangleF In plist
If r.Width >= max * 0.333 Then
e.Graphics.FillEllipse(Brushes.Red, r.X - 5, r.Y - 5, 10, 10)
e.Graphics.DrawString((r.Height / 10).ToString(Format("f2")) & " %", _
Me.Font, Brushes.Yellow, 2, 10)
Exit For
End If
Next Die Berechnung erfogt unsichtbar im G-Path und ist unabhängig von der Anzeige
MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 20.02.07 15:50 |
| Hallo GPM
Danke für deine erstklassige Hilfe!
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 23.02.07 09:34 |
| GPM schrieb:
Zitat: | | In plist(plist.Count - 1).Width steht die Gesamtlänge der Kurve
Nun brauchst Du nur die Liste nach dem Punkt zu durchsuchen
wo die Länge 1/3 ist.
Dim max As Int32 = plist(plist.Count - 1).Width
For Each r As RectangleF In plist
If r.Width >= max * 0.333 Then
e.Graphics.FillEllipse(Brushes.Red, r.X - 5, r.Y - 5,
10, 10)
e.Graphics.DrawString((r.Height /
10).ToString(Format("f2")) & " %",
Me.Font, Brushes.Yellow, 2, 10)
Exit For
End If
Next Die Berechnung erfogt unsichtbar im G-Path und ist unabhängig
von der Anzeige
MfG GPM
| |
Hallo GPM
Habe wieder einmal mich in das Thema reingehängt.
Da die Länge mir nun bekannt ist, ist es ja einfach die Koordinaten zu bestimmen.
Nur schreibst du, das die Berechnung unabhängig von der Anzeige berechnet wird ...
Wenn ich jedoch das Fenster maximiere (Zeichnung im Picturebox und skaliert mit), ändert sich (logischerweise?) auch die Länge in plist.
Da die Skalierung gleich ist, ist das Ergebniss ja ident, nur frage ich hier nach, weil ich eine bestimmte mind. Auflösung in der Berechnung haben möchte. Mir scheint, je größer die gezeichnete Bezierkurve, desto länger ist diese (logisch) und desto feiner könnte ich Zwischenergebnisse berechnen.
Möchte ja nicht unbedingt nur Ganzzahlen dazwischen, sondern eventuell in den 3 Stelligen Kommabereich ... hier würde eine große Anzeige genauer Berechnet werden (Rundungen).
Habe auch noch das "Problem", das wenn ich das Fenster skaliere, ich zwar immer 0% beim Ausgangspunkt habe, aber sobald ich vergrößere, ich am Endpunkt unter 100% bin (99,8578483 irgendwas)
Muss ich noch genauer studieren, wollts aber mal erwähnen.
Dein Code ist total pipifein Danke dir
Aber eventuell gestattest nocheinmal die Frage: Riesengroß zeichnen (1280x1024) ergibt ein genaueres Ergebnis wie bei 100x50?
Eigentlich von dir schon beantwortet:
unabhängig der Anzeige wird berechnet.
Nur scheint mir das hier anders zu sein, bzw habe ich was falsch gemacht oder noch nich verstanden.
Danke dir vielmals
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 23.02.07 09:38 |
| Verflixt, wieder zu schnell auf senden geklickt
Die Berechnung in Prozent habe ich angepaßt:
ListBox1.Items.Add(100 - ((r.Y - 10) / ((pic2.Height - 20) / 100)) & " %") in der Picturebox ist runderum (links-rechts,oben-unten) ein freier Platz von 10 Pixel.
Die Info, weil sonst die Angabe hier nicht richtig wäre.
und bei grossem Fenster habe ich beim Endpunkt selten 100% ... sondern 99,8943655...
Rundungsproblem?
Die Schleife habe ich von:
1 To ts-1 auf
0 To ts geändert. | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 23.02.07 11:16 |
| Berechnung unabhängig von der Anzeige heißt nur die Kurve muß für die Berechnung nicht sichtbar sein.
Da die Berechnung ja ohne Formel nur an der nicht sichtbaren Kurve im G-Path erfolgt, ist die Genauigkeit halt abhängig von deren Breite / Höhe.
100 Pixel =1% Auflösung
400 Pixel = 0,25% Auflösung
1000 Pixel = 0,1% Auflösung
Die Breite / Höhe sollte somit durch 100 teilbar sein.
Es ist halt nur ein einfacher Ersatz für eine scheinbar nicht gerade einfache Mathelösung.
MfG GPM | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: Hannes H. | Datum: 23.02.07 12:21 |
| Perfekt erklärt!
Vielen Dank
Hannes | |
Re: Fade-In,Fade-Out nicht linear | | | Autor: GPM | Datum: 25.02.07 11:54 |
| Die Berechnung wird ja an einer realen Bezierkurve im G-Path vorgenommen. Somit ist
die Grenze für eine sinnvolle Berechnung schnell erreicht. Der Versuch die Werte mit 1000
malzunehmen muß scheitern. Ein G-Path von 1000 x 1000 hat schon 1.000.000 Punkte.
Wäre er nur 10 x so breit und hoch sind das schon 100.000.000 mögliche Punkte.Für
sehr hohe Auflösungen wirst Du wohl nach einer andern Lösung suchen müssen.
MfG GPM | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevGraph (VB/VBA)
Grafische Auswertungen
Präsentieren Sie Ihre Daten mit wenig Aufwand in grafischer Form. sevGraph unterstützt hierbei Balken-, Linien- und Stapel-Diagramme (Stacked Bars), sowie 2D- und 3D-Tortendiagramme und arbeitet vollständig datenbankunabhängig! Weitere InfosTipp des Monats Access-Tools Vol.1
Über 400 MByte Inhalt
Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB
Nur 24,95 EURWeitere Infos
|