Blitzgenerator

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

 

Hangman

Betreff: Blitzgenerator

BeitragMi, Aug 06, 2014 2:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Community!

Ich brauchte für ein Projekt einen Algorithmus der Blitze erzeugen kann und habe mir mangels bereits verfügbarem Code selbst einen geschrieben. Damit der nächste das nicht mehr machen muss... oder zumindest nicht bei Null anfangen muss, hier der Code:

Version 1: www.blitzforum.de/upload/file.php?id=12876
Version 2 (Update von DAK):
BlitzMax: [AUSKLAPPEN]
Type TLightning
Const MIN_SEG_LENGTH:Int = 20 'Minimum segment length
Const MIN_SEG_BRANCH_LENGTH:Int = 5 'Minimum segment length on branches
Const BRANCH_ANGLE_MOD:Int = 40 'Max angle difference between mainlightning and branches
Const GLOWCOLOR_R:Int = 100
Const GLOWCOLOR_G:Int = 100
Const GLOWCOLOR_B:Int = 255
Field segments:TList = CreateList() 'List of segments of the mainlightning
Field branches:TList = CreateList() 'List of branches
Field branches2:TList = CreateList() 'Branches of the segmentized branches
Field generations:Int = 4 'Iterations of seperation of the mainlightning
Field offset:Int = 10 'Segments offset


Rem
bbdoc:Creates a new lightning from x1, y1 to x2, y2.
Public Function
End Rem

Function getInstance:TLightning(x1:Int, y1:Int, x2:Int, y2:Int)
Local instance:TLightning = New TLightning
instance.setStartEndPoint(x1, y1, x2, y2)

Return instance
End Function


Rem
bbdoc:Sets new start- and endpoint coordinates.
Public Method
End Rem

Method setStartEndPoint(x1:Int, y1:Int, x2:Int, y2:Int)
'Create segment from x1,y1 to x2,y2
Local startpoint:TPoint = TPoint.getInstance(x1, y1)
Local endpoint:TPoint = TPoint.getInstance(x2, y2)
Local firstSeg:TSegment = TSegment.getInstance(startpoint, endpoint)

'Remove old lightning
Self.segments.Clear()
Self.branches.Clear()
Self.branches2.Clear()

'Create the lightning out of the first segment
Self.segments.AddFirst(firstSeg)
Self.segmentize(Self.segments, Self.generations, Self.offset)
Self.branches = Self.createBranches(Self.segments)
Self.segmentize(Self.branches, Self.generations - 1, Self.offset - 7, True)
Self.branches2 = Self.createBranches(Self.branches)
Self.segmentize(Self.branches2, Self.generations - 3, Self.offset - 7, True)
End Method


Rem
bbdoc:Draws the lightning (Scale must be set to 1.0/1.0)
Public Method
End Rem

Method draw()
SetBlend(ALPHABLEND)

'Branch2 Glow
Self.setDrawings(0.4, 3, True)
Self.drawSegments(Self.branches2)
'Branches2
Self.setDrawings(0.5, 1)
Self.drawSegments(Self.branches2)

'Branch Glow
Self.setDrawings(0.5, 5, True)
Self.drawSegments(Self.branches)
'Branches
Self.setDrawings(0.6, 1)
Self.drawSegments(Self.branches)

'Glow Paths
Self.setDrawings(0.09, 20, True)
Self.drawSegments(Self.segments)
Self.setDrawings(0.25, 11, True)
Self.drawSegments(Self.segments)
Self.setDrawings(0.55, 6, True)
Self.drawSegments(Self.segments)
'Original Paths
SetColor(255, 255, 255)
SetAlpha(1.0)
Local counter:Int = 0
For Local seg:TSegment = EachIn Self.segments
counter:+1
Local thickness:Float = 0.3 * Float(Self.segments.Count() - counter)
If thickness < 2.0 Then thickness = 2.0
SetLineWidth(thickness)
DrawLine(seg.startpoint.x, seg.startpoint.y, seg.endpoint.x, seg.endpoint.y)
Next
End Method


Rem
bbdoc:Private Method (don__COMMENT18__
Draws a list of segments.
End Rem

Method drawSegments(givenList:TList)
Local realLineWidth:Float = GetLineWidth()
For Local seg:TSegment = EachIn givenList
Local lineWidth:Float = realLineWidth/2

Local ps1point:TPoint
Local ps2point:TPoint
Local pe1point:TPoint
Local pe2point:TPoint
Local lastSeg:TSegment = seg.lastSegment
Local nextSeg:TSegment = seg.nextSegment

Local tvec:TPoint = seg.endpoint.sub(seg.startpoint)
Local tvecn:TPoint = tvec.normalize()
Local tnorm:TPoint = tvec.normalize().normal()

If (lastSeg=Null) Then
ps1point = seg.startpoint.add(tnorm.mult(lineWidth))
ps2point = seg.startpoint.add(tnorm.mult(-lineWidth))
Else
Local lvec:TPoint = lastSeg.endpoint.sub(lastSeg.startpoint)
Local lnorm:TPoint = lvec.normalize().normal()

ps1point = seg.startpoint.add(lnorm.mult(lineWidth))
ps2point = seg.startpoint.add(lnorm.mult(-lineWidth))
EndIf

If (nextSeg=Null) Then
lineWidth = lineWidth/2
EndIf

pe1point = seg.endpoint.add(tnorm.mult(-lineWidth))
pe2point = seg.endpoint.add(tnorm.mult(lineWidth))


Local corners:Float[] = [ps1point.x,ps1point.y,ps2point.x,ps2point.y,pe1point.x,pe1point.y,pe2point.x,pe2point.y]

DrawPoly(corners)

SetColor(TLightning.GLOWCOLOR_R, TLightning.GLOWCOLOR_G, TLightning.GLOWCOLOR_B)
Next
End Method


Rem
bbdoc:Private Method (don__COMMENT19__
Sets the color to "Glow-Color"
End Rem

Method setDrawings(alpha:Float, lineThickness:Float, isGlowing:Byte = False)
SetColor(255, 255, 255)
If isGlowing Then SetColor(TLightning.GLOWCOLOR_R, TLightning.GLOWCOLOR_G, TLightning.GLOWCOLOR_B)
SetAlpha(alpha)
SetLineWidth(lineThickness)
End Method


Rem
bbdoc:Private Method (don__COMMENT20__
Splits a line (segment) into two lines, which are moved by maxOffset at one point (start or endpoint of the line).
End Rem

Method segmentize(givenList:TList, generations:Int, offset:Int, isBranch:Byte = False)
'Preconditions
If givenList.IsEmpty() Then Return
Local minLength:Int = TLightning.MIN_SEG_LENGTH
If isBranch Then minLength = TLightning.MIN_SEG_BRANCH_LENGTH

'Start segmentation
For Local i:Int = 1 To generations
Local workList:TList = givenList.Copy()
For Local seg:TSegment = EachIn workList

'Check if the segments length allows a split into 2 segments
If TDistance.pointToPoint(seg.startpoint.x, seg.startpoint.y, seg.endpoint.x, seg.endpoint.y) >= minLength Then
'The original segment is obsolete, as we replace it with 2 new ones
Local lastSegment:TSegment = seg.lastSegment
Local nextSegment:TSegment = seg.nextSegment
givenList.Remove(seg)

Local midpoint:TPoint = seg.getMidPoint()
Local randomAngle:Int = 90
If Rand(1, 2) = 1 Then randomAngle = -90
'Move the midpoint
midpoint.x:+(Cos(seg.angle + randomAngle) * offset)
midpoint.y:+(Sin(seg.angle + randomAngle) * offset)

'Add the new segments
Local seg1:TSegment = TSegment.getInstance(seg.startpoint, midpoint)
Local seg2:TSegment = TSegment.getInstance(midpoint, seg.endpoint)
seg1.lastSegment = lastSegment
seg1.nextSegment = seg2
seg2.lastSegment = seg1
seg2.nextSegment = nextSegment

If (lastSegment<>Null) Then lastSegment.nextSegment = seg1
If (nextSegment<>Null) Then nextSegment.lastSegment = seg2

givenList.AddLast(seg1)
givenList.AddLast(seg2)
End If
Next
Next
End Method


Rem
bbdoc:Private Method (don__COMMENT27__
Creates a branch at every segments startpoint.
End Rem

Method createBranches:TList(givenList:TList)
'Preconditions
If givenList.IsEmpty() Then Return Null

Local returnList:TList = New TList
Local i:Int = 0

For Local seg:TSegment = EachIn givenList
i:+1
Local branchAngle:Int = seg.angle + Rand(-TLightning.BRANCH_ANGLE_MOD, TLightning.BRANCH_ANGLE_MOD)
Local branchLength:Int = Float((Rnd(1.0, 3.0) * TDistance.pointToPoint(seg.startpoint.x, seg.startpoint.y, seg.endpoint.x, seg.endpoint.y))) * Float((Float(i) / Float(givenList.Count())))
Local branchX:Int = seg.endpoint.x + Cos(branchAngle) * branchLength
Local branchY:Int = seg.endpoint.y + Sin(branchAngle) * branchLength
Local branchpoint:Tpoint = TPoint.getInstance(branchX, branchY)

Local branch:TSegment = TSegment.getInstance(seg.endpoint, branchpoint)

returnList.AddLast(branch)
Next
Return returnList
End Method

End Type



Rem
bbdoc:Defines a linesegment between two points in 2D space.
End Rem

Type TSegment
Field startpoint:TPoint
Field endpoint:TPoint
Field angle:Int
Field lastSegment:TSegment
Field nextSegment:TSegment


Rem
bbdoc:Constructor.
End Rem

Function getInstance:TSegment(startpoint:TPoint, endpoint:TPoint)
Local instance:TSegment = New TSegment
instance.startpoint = startpoint
instance.endpoint = endpoint
instance.angle = ATan2((endpoint.y - startpoint.y), (endpoint.x - startpoint.x))
Return instance
End Function


Rem
bbdoc:Returns a point on the mid of the segment.
End Rem

Method getMidPoint:TPoint()
Local midpoint:Tpoint = New TPoint
midpoint.x = (startpoint.x + endpoint.x)/2
midpoint.y = (startpoint.y + endpoint.y)/2
Return midpoint
End Method
End Type



Rem
bbdoc:2D Point helper class.
End Rem

Type TPoint
Field x:Float
Field y:Float


Rem
bbdoc:Constructor.
End Rem

Function getInstance:TPoint(x:Float, y:Float)
Local instance:TPoint = New TPoint
instance.x = x
instance.y = y
Return instance
End Function

Rem
bbdoc:Addiert zwei TPoints zusammen (Vektorrechnung)
End Rem

Method add:TPoint(other:TPoint)
Return getInstance(x+other.x,y+other.y)
End Method

Rem
bbdoc:Subtrahiert zwei TPoints (Vektorrechnung)
End Rem

Method sub:TPoint(other:TPoint)
Return getInstance(x-other.x,y-other.y)
End Method

Rem
bbdoc:Multipliziert einen TPoint mit einem Skalar (Vektorrechnung)
End Rem

Method mult:TPoint(f:Float)
Return getInstance(x*f,y*f)
End Method

Rem
bbdoc:Liefert die Laenge des Vektors (Vektorrechnung)
End Rem

Method length:Float()
Return Sqr(x*x+y*y)
End Method

Rem
bbdoc:Normalisiert den Vektor (Vektorrechnung)
End Rem

Method normalize:TPoint()
Return mult(1.0/length())
End Method

Rem
bbdoc:Erstellt einen Normalvektor (Vektorrechnung)
End Rem

Method normal:TPoint()
Return getInstance(y,-x)
End Method

Rem
bbdoc:Liefert das Skalarprodukt zweier Vektoren (Vektorrechnung)
End Rem

Method dot:Float(other:TPoint)
Return (x*other.x+y*other.y)
End Method
End Type



Rem
bbdoc:Helper tool to calculate the distance between 2 points in a 2D environment.
End Rem

Type TDistance Abstract

Rem
bbdoc:Berechnet die Distanz zwischen 2 Punkten.
End Rem

Function pointToPoint:Double(x1:Double, y1:Double, x2:Double, y2:Double)
Return Sqr(TDistance.quad(x2 - x1) + TDistance.quad(y2 - y1))
End Function


Rem
bbdoc:Quadriert einen Integer.
End Rem

Function quad:Double(v:Double)
Return (v * v)
End Function

End Type


+ Demo: www.blitzforum.de/upload/file.php?id=12877
BlitzMax: [AUSKLAPPEN]
'Test
Include "Lightning.bmx"

Graphics 1024, 768
Global blitz:TLightning = TLightning.getInstance(100, 100, 500, 500)
Global oldMausX:Int
Global oldMausY:Int
SetClsColor(10, 10, 10)

Repeat
Cls

If MouseX() <> oldMausX Or MouseY() <> oldMausY Then
oldMausX = MouseX()
oldMausY = MouseY()
blitz.setStartEndPoint(100, 100, MouseX(), MouseY())
End If

blitz.draw()

Flip
Until AppTerminate()


Optisch wie ich finde brauchbar, allerdings ist auch noch deutlich Potential nach oben... also wer das ganze noch verbessern möchte, nur zu!
Aus Faulheitsgründen habe ich auch nicht mehr Funktionen hinzugefügt, um den Blitz zu modifizieren.

So siehts aus:
user posted image

Und lässt sich so simpel wie folgt benutzen:
BlitzMax: [AUSKLAPPEN]
Local blitz:TLightning = TLightning.getInstance(startX, startY, endX, endY)
blitz.draw()
  • Zuletzt bearbeitet von Hangman am Do, Aug 07, 2014 16:51, insgesamt 2-mal bearbeitet

DAK

BeitragMi, Aug 06, 2014 6:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Schaut sehr cool aus!

Ich hätt noch zwei Verbesserungsvorschläge:

1) Dein Haupt-Ast könnte noch etwas smoothing vertragen. Bei Ecken und vor allem dem Ende des Haupt-Astes sieht man doch unschöne Kanten. Was du machen könntest wäre ein rundes Segment machen (so ähnlich wie du es jetzt schon machst nur mit Ovals statt mit Lines) und das in jede Ecke zeichnen, einfach als unterstes, damit es nur die übrigen Ecken ausfüllt.

2) Es wäre cool, wenn man einen Blitz quasi wachsen lassen könnte, also dass er erst langsamer entsteht, als sofort da zu sein.

Sonst echt schöner Effekt!
Gewinner der 6. und der 68. BlitzCodeCompo

Xeres

Moderator

BeitragMi, Aug 06, 2014 10:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Bitte paste den Code in deinen Beitrag, danke.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Hangman

BeitragMi, Aug 06, 2014 22:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke @DAK
Ich werde mich da selbst nicht mehr dran begeben.
Aber vielleicht möchte jemand anderes den Algo noch verbessern, würde ich natürlich auch begrüßen und den Beitrag bei Verbesserungen entsprechend editieren.
Ich habe Berthold gebrochen.

DAK

BeitragDo, Aug 07, 2014 15:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab es zuerst mit den Kreisen probiert, das hat aber nicht so schön ausgeschaut. Deswegen hab ich das DrawLine durch DrawPoly ersetzt und damit die Ecken komplett entfernt. Außerdem hab ich das Ende jedes Segments dass keine Nachfolger hat um die Hälfte verschmälert. Das sorgt für einen schöneren Abschluss.

Die Unterschiede werden besonders deutlich, je näher der Blitz an 45° kommt. Bei einem Blitz, der gerade von oben nach unten geht sieht man die Schwächen von DrawLine kaum.

user posted image

BlitzMax: [AUSKLAPPEN]
Type TLightning
Const MIN_SEG_LENGTH:Int = 20 'Minimum segment length
Const MIN_SEG_BRANCH_LENGTH:Int = 5 'Minimum segment length on branches
Const BRANCH_ANGLE_MOD:Int = 40 'Max angle difference between mainlightning and branches
Const GLOWCOLOR_R:Int = 100
Const GLOWCOLOR_G:Int = 100
Const GLOWCOLOR_B:Int = 255
Field segments:TList = CreateList() 'List of segments of the mainlightning
Field branches:TList = CreateList() 'List of branches
Field branches2:TList = CreateList() 'Branches of the segmentized branches
Field generations:Int = 4 'Iterations of seperation of the mainlightning
Field offset:Int = 10 'Segments offset


Rem
bbdoc:Creates a new lightning from x1, y1 to x2, y2.
Public Function
End Rem

Function getInstance:TLightning(x1:Int, y1:Int, x2:Int, y2:Int)
Local instance:TLightning = New TLightning
instance.setStartEndPoint(x1, y1, x2, y2)

Return instance
End Function


Rem
bbdoc:Sets new start- and endpoint coordinates.
Public Method
End Rem

Method setStartEndPoint(x1:Int, y1:Int, x2:Int, y2:Int)
'Create segment from x1,y1 to x2,y2
Local startpoint:TPoint = TPoint.getInstance(x1, y1)
Local endpoint:TPoint = TPoint.getInstance(x2, y2)
Local firstSeg:TSegment = TSegment.getInstance(startpoint, endpoint)

'Remove old lightning
Self.segments.Clear()
Self.branches.Clear()
Self.branches2.Clear()

'Create the lightning out of the first segment
Self.segments.AddFirst(firstSeg)
Self.segmentize(Self.segments, Self.generations, Self.offset)
Self.branches = Self.createBranches(Self.segments)
Self.segmentize(Self.branches, Self.generations - 1, Self.offset - 7, True)
Self.branches2 = Self.createBranches(Self.branches)
Self.segmentize(Self.branches2, Self.generations - 3, Self.offset - 7, True)
End Method


Rem
bbdoc:Draws the lightning (Scale must be set to 1.0/1.0)
Public Method
End Rem

Method draw()
SetBlend(ALPHABLEND)

'Branch2 Glow
Self.setDrawings(0.4, 3, True)
Self.drawSegments(Self.branches2)
'Branches2
Self.setDrawings(0.5, 1)
Self.drawSegments(Self.branches2)

'Branch Glow
Self.setDrawings(0.5, 5, True)
Self.drawSegments(Self.branches)
'Branches
Self.setDrawings(0.6, 1)
Self.drawSegments(Self.branches)

'Glow Paths
Self.setDrawings(0.09, 20, True)
Self.drawSegments(Self.segments)
Self.setDrawings(0.25, 11, True)
Self.drawSegments(Self.segments)
Self.setDrawings(0.55, 6, True)
Self.drawSegments(Self.segments)
'Original Paths
SetColor(255, 255, 255)
SetAlpha(1.0)
Local counter:Int = 0
For Local seg:TSegment = EachIn Self.segments
counter:+1
Local thickness:Float = 0.3 * Float(Self.segments.Count() - counter)
If thickness < 2.0 Then thickness = 2.0
SetLineWidth(thickness)
DrawLine(seg.startpoint.x, seg.startpoint.y, seg.endpoint.x, seg.endpoint.y)
Next
End Method


Rem
bbdoc:Private Method (don__COMMENT18__
Draws a list of segments.
End Rem

Method drawSegments(givenList:TList)
Local realLineWidth:Float = GetLineWidth()
For Local seg:TSegment = EachIn givenList
Local lineWidth:Float = realLineWidth/2

Local ps1point:TPoint
Local ps2point:TPoint
Local pe1point:TPoint
Local pe2point:TPoint
Local lastSeg:TSegment = seg.lastSegment
Local nextSeg:TSegment = seg.nextSegment

Local tvec:TPoint = seg.endpoint.sub(seg.startpoint)
Local tvecn:TPoint = tvec.normalize()
Local tnorm:TPoint = tvec.normalize().normal()

If (lastSeg=Null) Then
ps1point = seg.startpoint.add(tnorm.mult(lineWidth))
ps2point = seg.startpoint.add(tnorm.mult(-lineWidth))
Else
Local lvec:TPoint = lastSeg.endpoint.sub(lastSeg.startpoint)
Local lnorm:TPoint = lvec.normalize().normal()

ps1point = seg.startpoint.add(lnorm.mult(lineWidth))
ps2point = seg.startpoint.add(lnorm.mult(-lineWidth))
EndIf

If (nextSeg=Null) Then
lineWidth = lineWidth/2
EndIf

pe1point = seg.endpoint.add(tnorm.mult(-lineWidth))
pe2point = seg.endpoint.add(tnorm.mult(lineWidth))


Local corners:Float[] = [ps1point.x,ps1point.y,ps2point.x,ps2point.y,pe1point.x,pe1point.y,pe2point.x,pe2point.y]

DrawPoly(corners)
Next
End Method


Rem
bbdoc:Private Method (don__COMMENT19__
Sets the color to "Glow-Color"
End Rem

Method setDrawings(alpha:Float, lineThickness:Float, isGlowing:Byte = False)
SetColor(255, 255, 255)
If isGlowing Then SetColor(TLightning.GLOWCOLOR_R, TLightning.GLOWCOLOR_G, TLightning.GLOWCOLOR_B)
SetAlpha(alpha)
SetLineWidth(lineThickness)
End Method


Rem
bbdoc:Private Method (don__COMMENT20__
Splits a line (segment) into two lines, which are moved by maxOffset at one point (start or endpoint of the line).
End Rem

Method segmentize(givenList:TList, generations:Int, offset:Int, isBranch:Byte = False)
'Preconditions
If givenList.IsEmpty() Then Return
Local minLength:Int = TLightning.MIN_SEG_LENGTH
If isBranch Then minLength = TLightning.MIN_SEG_BRANCH_LENGTH

'Start segmentation
For Local i:Int = 1 To generations
Local workList:TList = givenList.Copy()
For Local seg:TSegment = EachIn workList

'Check if the segments length allows a split into 2 segments
If TDistance.pointToPoint(seg.startpoint.x, seg.startpoint.y, seg.endpoint.x, seg.endpoint.y) >= minLength Then
'The original segment is obsolete, as we replace it with 2 new ones
Local lastSegment:TSegment = seg.lastSegment
Local nextSegment:TSegment = seg.nextSegment
givenList.Remove(seg)

Local midpoint:TPoint = seg.getMidPoint()
Local randomAngle:Int = 90
If Rand(1, 2) = 1 Then randomAngle = -90
'Move the midpoint
midpoint.x:+(Cos(seg.angle + randomAngle) * offset)
midpoint.y:+(Sin(seg.angle + randomAngle) * offset)

'Add the new segments
Local seg1:TSegment = TSegment.getInstance(seg.startpoint, midpoint)
Local seg2:TSegment = TSegment.getInstance(midpoint, seg.endpoint)
seg1.lastSegment = lastSegment
seg1.nextSegment = seg2
seg2.lastSegment = seg1
seg2.nextSegment = nextSegment

If (lastSegment<>Null) Then lastSegment.nextSegment = seg1
If (nextSegment<>Null) Then nextSegment.lastSegment = seg2

givenList.AddLast(seg1)
givenList.AddLast(seg2)
End If
Next
Next
End Method


Rem
bbdoc:Private Method (don__COMMENT27__
Creates a branch at every segments startpoint.
End Rem

Method createBranches:TList(givenList:TList)
'Preconditions
If givenList.IsEmpty() Then Return Null

Local returnList:TList = New TList
Local i:Int = 0

For Local seg:TSegment = EachIn givenList
i:+1
Local branchAngle:Int = seg.angle + Rand(-TLightning.BRANCH_ANGLE_MOD, TLightning.BRANCH_ANGLE_MOD)
Local branchLength:Int = Float((Rnd(1.0, 3.0) * TDistance.pointToPoint(seg.startpoint.x, seg.startpoint.y, seg.endpoint.x, seg.endpoint.y))) * Float((Float(i) / Float(givenList.Count())))
Local branchX:Int = seg.endpoint.x + Cos(branchAngle) * branchLength
Local branchY:Int = seg.endpoint.y + Sin(branchAngle) * branchLength
Local branchpoint:Tpoint = TPoint.getInstance(branchX, branchY)

Local branch:TSegment = TSegment.getInstance(seg.endpoint, branchpoint)

returnList.AddLast(branch)
Next
Return returnList
End Method

End Type



Rem
bbdoc:Defines a linesegment between two points in 2D space.
End Rem

Type TSegment
Field startpoint:TPoint
Field endpoint:TPoint
Field angle:Int
Field lastSegment:TSegment
Field nextSegment:TSegment


Rem
bbdoc:Constructor.
End Rem

Function getInstance:TSegment(startpoint:TPoint, endpoint:TPoint)
Local instance:TSegment = New TSegment
instance.startpoint = startpoint
instance.endpoint = endpoint
instance.angle = ATan2((endpoint.y - startpoint.y), (endpoint.x - startpoint.x))
Return instance
End Function


Rem
bbdoc:Returns a point on the mid of the segment.
End Rem

Method getMidPoint:TPoint()
Local midpoint:Tpoint = New TPoint
midpoint.x = (startpoint.x + endpoint.x)/2
midpoint.y = (startpoint.y + endpoint.y)/2
Return midpoint
End Method
End Type



Rem
bbdoc:2D Point helper class.
End Rem

Type TPoint
Field x:Float
Field y:Float


Rem
bbdoc:Constructor.
End Rem

Function getInstance:TPoint(x:Float, y:Float)
Local instance:TPoint = New TPoint
instance.x = x
instance.y = y
Return instance
End Function

Rem
bbdoc:Addiert zwei TPoints zusammen (Vektorrechnung)
End Rem

Method add:TPoint(other:TPoint)
Return getInstance(x+other.x,y+other.y)
End Method

Rem
bbdoc:Subtrahiert zwei TPoints (Vektorrechnung)
End Rem

Method sub:TPoint(other:TPoint)
Return getInstance(x-other.x,y-other.y)
End Method

Rem
bbdoc:Multipliziert einen TPoint mit einem Skalar (Vektorrechnung)
End Rem

Method mult:TPoint(f:Float)
Return getInstance(x*f,y*f)
End Method

Rem
bbdoc:Liefert die Laenge des Vektors (Vektorrechnung)
End Rem

Method length:Float()
Return Sqr(x*x+y*y)
End Method

Rem
bbdoc:Normalisiert den Vektor (Vektorrechnung)
End Rem

Method normalize:TPoint()
Return mult(1.0/length())
End Method

Rem
bbdoc:Erstellt einen Normalvektor (Vektorrechnung)
End Rem

Method normal:TPoint()
Return getInstance(y,-x)
End Method

Rem
bbdoc:Liefert das Skalarprodukt zweier Vektoren (Vektorrechnung)
End Rem

Method dot:Float(other:TPoint)
Return (x*other.x+y*other.y)
End Method
End Type



Rem
bbdoc:Helper tool to calculate the distance between 2 points in a 2D environment.
End Rem

Type TDistance Abstract

Rem
bbdoc:Berechnet die Distanz zwischen 2 Punkten.
End Rem

Function pointToPoint:Double(x1:Double, y1:Double, x2:Double, y2:Double)
Return Sqr(TDistance.quad(x2 - x1) + TDistance.quad(y2 - y1))
End Function


Rem
bbdoc:Quadriert einen Integer.
End Rem

Function quad:Double(v:Double)
Return (v * v)
End Function

End Type
Gewinner der 6. und der 68. BlitzCodeCompo
  • Zuletzt bearbeitet von DAK am Fr, Aug 08, 2014 19:48, insgesamt einmal bearbeitet
 

Hangman

BeitragDo, Aug 07, 2014 16:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr schön! Gefällt mir sehr gut, auch die blau gehaltenen Abzweigungen sehen etwas natürlicher aus.
PS: Beitrag oben editiert.
Ich habe Berthold gebrochen.

DAK

BeitragFr, Aug 08, 2014 19:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Die waren eigentlich ein Bug, der mir nicht aufgefallen ist.

Ich hab den Code oben geupdatet.
Gewinner der 6. und der 68. BlitzCodeCompo

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group