Schmidt
1/8/2012 5:25:00 AM
Am 07.01.2012 15:32, schrieb Larry Serflaten:
> ...
> A series of circles would be OK also, as long
> as all grid cells get filled.
I take it, that the speed of the check-routine is
of the essence (and not the drawing/visualizing-code)?
Anyways, below is some fast snippet, which is accomplishing
the task in a "non-spiralic, but concentric fashion",
extending the Radius in single Pixel-Increments -
thereby wasting only about 27% of the time in
Pixel-DoubleChecks (meaning 73% is ending up white,
all the rest of the concentric area is yellow Pixels).
Extra-Code, "to keep everything white" would
need a more complex check-routine, which
in the end would run slower than the version
below (with the "27% overscan").
Time needed (on a Intel 2.8GHz-CPU) using a 300x300
Grid, checking the Radius in a loop from 1 to 148
needs about 0.2-0.3msec (native-Code, all Options checked).
Just in case, this is for a fast circular
Collision-Detection, then there's even more
efficient ways, to accomplish that (depending
on the "shape of the other objects around").
'***Into a Form, then click the Form
Option Explicit
Private Declare Function StretchDIBits& Lib "gdi32" (ByVal hDC&, _
ByVal x&, ByVal y&, ByVal dx&, ByVal dy&, ByVal SrcX&, ByVal SrcY&, _
ByVal Srcdx&, ByVal Srcdy&, lpBits As Any, lpBitsInfo As Any, ByVal _
wUsage&, ByVal dwRop&)
Private Const SqPxls& = 300
Private Const CX& = SqPxls \ 2, CY& = SqPxls \ 2
Private Grid(0 To SqPxls, 0 To SqPxls) As Long
Private Pxls(0 To SqPxls, 0 To SqPxls) As Long
Private Sub Form_Click()
Dim R As Double, T As Single
Erase Grid
T = Timer
For R = 1 To SqPxls \ 2 - 2
CheckAlongRadius R
' If R Mod 5 = 0 Then ShowGrid
Next R
Caption = Timer - T
ShowGrid
End Sub
'this is acutally performing a "quadrant-based"
'circular check, using the circle-formula: R^2 = X^2 + Y^2
'(trigon. functions as Sin/Cos are much slower than
' simple Mul/Add-Integer-Ops)
Private Sub CheckAlongRadius(ByVal R As Long)
Dim x As Long, y As Long, RSquare As Long
RSquare = R * R
x = 0: y = R 'let's start at this point
Do
Grid(CX + x, CY + y) = Grid(CX + x, CY + y) + 1
Grid(CX - x, CY - y) = Grid(CX - x, CY - y) + 1
Grid(CX + y, CY - x) = Grid(CX + y, CY - x) + 1
Grid(CX - y, CY + x) = Grid(CX - y, CY + x) + 1
If Abs((x + 1) * (x + 1) + y * y - RSquare) > _
Abs((y - 1) * (y - 1) + x * x - RSquare) Then _
y = y - 1 Else x = x + 1
Loop Until x = R And y = 0 'our "quadrant-finished"-condition
End Sub
Private Sub ShowGrid()
Dim x As Long, y As Long
For y = 0 To UBound(Grid, 2)
For x = 0 To UBound(Grid, 1)
Select Case Grid(x, y)
Case 0: Pxls(x, y) = vbBlack
Case 1: Pxls(x, y) = vbWhite
Case 2: Pxls(x, y) = vbCyan 'ending up yellow
Case Else: Pxls(x, y) = vbBlue 'ending up red
End Select
Next x
Next y
ScaleMode = vbPixels
DrawArr hDC, 0, 0, ScaleWidth, ScaleHeight
End Sub
Private Sub DrawArr(hDC, x, y, dx, dy)
Dim BI&(9)
BI(0) = 40
BI(1) = UBound(Pxls, 1) + 1
BI(2) = -UBound(Pxls, 2) + 1
BI(3) = 1 + 65536 * 32 '32bpp
StretchDIBits hDC, x, y, dx, dy, 0, 0, BI(1), Abs(BI(2)), _
Pxls(0, 0), BI(0), 0, vbSrcCopy
End Sub
Olaf