Working on a Crochet pattern creator for my wife. End goal is any 3 letters in a row (eventually numbers as well) in the center of some afghan. Created some of the letters in a grid (see the Big "A" image below). From that I MANUALLY created the list shown in the list image. What I want to attempt (but don't know quite where to start) is (at the click of some button) create a list of simple crochets as shown in the list image. As one who crochets (yeah, this old man can do that), I know that when you get to an end of a row, you reverse and go in the opposite direction until the end of that next row (and then reverse until completed), hence the Left and Right (I'll eventually replace those words with whatever it is called when you reverse (I forgot the name, just know how to do it with yarn.)
So, in the two images, if I were do code some event to create the list, that would be my next step. Once I get that figured out, I can do simple math (I hope!!!) and put the three letters next to each other. (Each letter has a white border on left and right as show in the "A" picture---4 whites).
Ideas on how to code (create that list) from that image (there are 28 rows and 20 columns)?
Sammi
EDIT: PS- that first line in the list should be one more white on each side and only 2 red (I changed it since I did the manual count).
Last edited by SamOscarBrown; Apr 5th, 2022 at 04:11 PM.
Actually, both (to your first question). I don't really NEED to create the pattern from a script, but do need to create the script from the pattern.
To your second question, the "A" image (which will be every letter of the English alphabet, along with numbers 1 through 9) is a GRID of command buttons (I used command buttons because I was attempting manually to create each letter --- clicking on the buttons to turn color from White to Red). It would have been nice if I could have figured out how to create each letter with code, but it is not necessary (I have done several, and when I am completed I will have a text file to read to 'recreate' each letter (which I have already coded and it works fine). So, when I said I don't need to create a grid from a script, I was referring to a grid of three letters in a row, rather than just one letter as I currently have done...but, not necessary.
I am working on, this morning, using three letters (and scripts created manually) to create a real script of all three letters in a row. If I don't get advice on how to 'parse the pattern (grid) to a single script (listbox example above), I'll eventually figure it out. Just have to wrap the brain around it a bit more, but really shouldn't be too hard.
I had. And probably should have (still could). Maybe I'll give it a try a bit later...just about got my three-letter scripts done (left to right works, gotta now do the right to lefts). But, this is with my manually created 'scripts' (listboxes).
When I finish this 3-letter thing, I'll attempt something with a flexgrid. BUT, before I get too far into that, I may relook how to create letters in that grid with code rather than manually like I did with the cmd buttons.
Well, got the 3-letter scripting coding done (printable).
Now instead of manually attempting to create a script for each letter (as my original reason for this thread), I'll take a stab at using a flexgrid as a start for the other letters I need to create a script for and try to develop THAT code.
Sam, are you allowed to go diagonal with the moves? If not, I don't think you can do it. And even if so, it's going to be a difficult (probably trial-and-error) task to figure out a single path that'll cover all the squares.
Also, something that comes to mind to me, in terms of figuring out which squares are to be crocheted, almost all of our fonts are truetype (which basically means it's an algorithm, and not hardcoded pixels, that are used to figure them out). But, they are dithered so they don't stay strictly black-and-white. But, we could possibly force that issue. Then, you'd have templates for any character and any font for your squares. Truth be told, as few squares as you're actually covering, the fonts would be a tiny size, but that's ok. Done that way, you could type out a word, and you'd have your proportional spacing and kerning all worked out for you. It actually sounds like an interesting project.
Type out your word in the program.
Scale the font down to a size that's only got something like 28 pixels for its height (as yours does).
Print it somewhere (maybe directly on the form).
Force to black-and-white.
Scale everything back up, using some multiple of 2, and using a strict pixel resize (no dithering).
Make it look like your MineSweeper image.
Calculate single-path per character for the crocheting.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
I created a basic sample using the MSFlexGrid.
You can just draw in the grid by selecting areas using the mouse.
Erasing is done by selecting an area while pressing the CTRL button.
The script is generated when pressing the script button.
@Elroy...that was what I was first pondering (how to create a letter (with code instead of a manual process). I will have to look at that, and give it a try (as an example). Will post later on that.
@Arnoutdv...pretty sharp! I did NOT yet analyze what you did (as far as the script creation), but did note a couple of anomalies when I 'drew' a "B"...note the first line...instead of "6W" on the right, it shows "2W" and then 4"W".
Been building a walk bridge at church this morning, and taking a short break before I go back out in the 83 degree weather for more 'outdoor' work...so will check out both suggestions from you two.
@Elroy...when "I" was 'drawing', I was simply using a command button to change its backcolor to red (or back to white on a mistake), so wasn't doing anything requiring a diagonal move. But your suggestion of using already made letters sounds intriguing. Wonder what the best font would be to use for that.
And, just to let ya know....I use my three scripts (one for each letter) in three listboxes, and then 'combine' them into one listbox by adding the W's separating the letters, and then putting them back together. Works for all odd (LEFT) rows, so then had to reverse the process on the even (RIGHT rows).
So these first two rows of the three letters:
would be:
Row 1--LEFT 12W,4R,16W,18R,12W,14R,6W
Row 2--RIGHT 5W,18R,9W,19R,17W,4R,12W (Row 2 is a reversed string (used an array to reverse each color)
@Elroy...when "I" was 'drawing', I was simply using a command button to change its backcolor to red (or back to white on a mistake), so wasn't doing anything requiring a diagonal move. But your suggestion of using already made letters sounds intriguing. Wonder what the best font would be to use for that.
Hey, I'm a touch bored right now. Let me play around with it and see what I can come up with.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
@Arnoutdv...pretty sharp! I did NOT yet analyze what you did (as far as the script creation), but did note a couple of anomalies when I 'drew' a "B"...note the first line...instead of "6W" on the right, it shows "2W" and then 4"W".
Oh yes of course, the MSFlexGrid uses .CellBackColor = 0 to erase the color, not the value of .BackColor
Code:
Private Sub pInvertCells()
Dim lRow As Long, lCol As Long
Dim lR1 As Long, lR2 As Long, lC1 As Long, lC2 As Long
With fgPattern
.Redraw = False
.FillStyle = flexFillSingle
pMinMax m_lStartRow, m_lEndRow, lR1, lR2
pMinMax m_lStartCol, m_lEndCol, lC1, lC2
For lRow = lR1 To lR2
.Row = lRow: .RowSel = lRow
For lCol = lC1 To lC2
.Col = lCol: .ColSel = lCol
If m_bErase Then .CellBackColor = 0 Else .CellBackColor = vbRed
Next lCol
Next
.Redraw = True
End With
End Sub
The following version fixes a bug when an entire row was red, and I've also added quite a few comments to help explain how it works in case you are interested:
Ok, I've come to a stopping place. Here are the things I haven't done:
Actually made it into a MineSweeper grid of boxes (but it does sort of look like it).
Figured out the paths for the actual crocheting.
A project is attached, but I wanted to show my work. Here's what a test looks like:
And here's the code in that form. There's also another module that just prompts for the font.
Code:
Option Explicit
Private Sub cmdSelectFont_Click()
Dim sFontName As String
sFontName = txtFontName.Text
If Len(sFontName) = 0& Then sFontName = "Segoe UI"
Dim nFontHeight As Single
nFontHeight = Val(txtFontHeight.Text)
If nFontHeight = 0! Then nFontHeight = 24!
'
ShowFont Me.hDC, Me.hWnd, sFontName, nFontHeight
'
If nFontHeight = 0! Then Exit Sub
'
txtFontName.Text = sFontName
txtFontHeight.Text = CStr(Int(nFontHeight)) ' We do the Int() because you can specify fractional sizes, and we don't want that.
End Sub
Private Sub cmdPixelate_Click()
If Val(txtFontHeight.Text) = 0 Then Exit Sub
If Len(txtText.Text) = 0& Then Exit Sub
'
' Setup picture box.
pic.AutoRedraw = True
pic.ScaleMode = vbPixels
pic.BackColor = vbWhite
'
' Get some things into local variables.
Dim iFontHeight As Long: iFontHeight = Val(txtFontHeight.Text)
Dim sText As String: sText = txtText.Text
'
' Set our font.
pic.FontName = txtFontName.Text
'
' Figure out point size from our pixel size.
pic.FontSize = 400! ' Just a starting place.
Do While pic.TextHeight(sText) > iFontHeight
pic.FontSize = pic.FontSize - 1!
Loop
'
' Show our text.
pic.Cls
pic.Print txtText.Text
'
' Remove dithering.
Dim x As Single
Dim y As Single
Dim color As Long
Dim brightness As Long
For x = 0! To pic.ScaleWidth - 1!
For y = 0! To pic.ScaleHeight - 1!
color = pic.Point(x, y)
brightness = (color And &HFF&) + (color And &HFF00&) \ &H100& + (color And &HFF0000) \ &H10000 ' Just add the colors together.
If brightness > 382& Then ' Middle brightness.
color = vbWhite
Else
color = vbBlack
End If
pic.PSet (x, y), color
Next
Next
'
' Find limits of where the text is actually drawn.
Dim xMin As Long: xMin = &H7FFFFFFF
Dim xMax As Long: xMax = &H7FFFFFFF
Dim yMin As Long: yMin = &H7FFFFFFF
Dim yMax As Long: yMax = &H7FFFFFFF
' Find xMin.
For x = 0! To pic.ScaleWidth - 1!
For y = 0! To pic.ScaleHeight - 1!
If pic.Point(x, y) <> vbWhite Then ' Loop until we find a pixel ON in the column.
xMin = CLng(x)
Exit For
End If
Next
If xMin <> &H7FFFFFFF Then Exit For
Next
' Find xMax.
For x = pic.ScaleWidth - 1! To 0! Step -1!
For y = 0! To pic.ScaleHeight - 1!
If pic.Point(x, y) <> vbWhite Then ' Loop until we find a pixel ON in the column, going backwards.
xMax = CLng(x)
Exit For
End If
Next
If xMax <> &H7FFFFFFF Then Exit For
Next
' Find yMin.
For y = 0! To pic.ScaleHeight - 1!
For x = 0! To pic.ScaleWidth - 1!
If pic.Point(x, y) <> vbWhite Then ' Loop until we find a pixel ON in the row.
yMin = CLng(y)
Exit For
End If
Next
If yMin <> &H7FFFFFFF Then Exit For
Next
' Find yMax.
For y = pic.ScaleHeight - 1! To 0! Step -1!
For x = 0! To pic.ScaleWidth - 1!
If pic.Point(x, y) <> vbWhite Then ' Loop until we find a pixel ON in the row, going backwards.
yMax = CLng(y)
Exit For
End If
Next
If yMax <> &H7FFFFFFF Then Exit For
Next
'
' Make an array of black & white text, removing any offsets (margins) in the picture box.
Dim pixels() As Long
ReDim pixels(xMax - xMin, yMax - yMin)
For x = CSng(xMin) To CSng(xMax)
For y = CSng(yMin) To CSng(yMax)
pixels(CLng(x) - xMin, CLng(y) - yMin) = pic.Point(x, y)
Next
Next
'
' Erase picture box again, and show text as a multiple of it's pixel size, pixelated for crocheting.
' We also use this setting as a margin.
Const ScreenPixelsPerBlock As Long = 8& ' This can be changed to whatever (some positive number).
pic.Cls
Dim iix As Long
Dim iiy As Long
Dim ix As Long
Dim iy As Long
For ix = 0& To UBound(pixels, 1&)
For iy = 0& To UBound(pixels, 2&)
If pixels(ix, iy) = vbBlack Then
' Make a block for the pixel.
For iix = 0& To ScreenPixelsPerBlock
For iiy = 0 To ScreenPixelsPerBlock ' V --- This +3 separates the pixels (crochet squares).
pic.PSet (ScreenPixelsPerBlock + ix * (ScreenPixelsPerBlock + 3&) + iix, _
ScreenPixelsPerBlock + iy * (ScreenPixelsPerBlock + 3&) + iiy), vbBlack
Next
Next
End If
Next
Next
'
' I'll stop here, but that pixels() 2D array can be used to make a grid of little MineSweeper squares, either ON or OFF.
End Sub
And, there's more to be done when prompting for the font. I didn't do anything with Bold, Underline, Italic, and other style settings.
Also, just as an FYI, you can change that ScreenPixelsPerBlock constant to make the blocks bigger or smaller. You can also change that +3& to make the blocks either more or less spread out.
Last edited by Elroy; Apr 6th, 2022 at 06:23 PM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
If you actually do make a grid of little MineSweeper controls, you could further tweak on it (turning blocks ON-or-OFF) and then re-calculate your crochet path.
Just an idea.
Also, just as another note, I didn't turn Y upside-down in any of my calculations (even the pixels() 2D array). There just wasn't any need in anything I did, but sometimes that "start at top" nature of Y in forms and picture boxes confuses people. It's not how you do it in geometry.
Last edited by Elroy; Apr 6th, 2022 at 06:32 PM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Also, I just read up, and it looks like Jpbro has been working on figuring out the paths.
Maybe put that work together with mine, and you'll be close.
(And I want to also make an "aside" comment. Sam is a wonderful helper in these forums, and many of us probably count him as a friend. When writing code for him, that makes a HUGE difference in my mind. Just wanted to say that for people who may be pouting because they didn't get code written for them.)
Last edited by Elroy; Apr 6th, 2022 at 06:38 PM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
As I said earlier---you guys are great---always willing to provide alternatives and suggestions.
In THIS case, I opted to go with the FlexGrid as Arnoutdv posted. I found it relatively easy to create all 26 English Alphabet Letters. As that is a one-time shot (I save each 'script' per letter to a text file), I was quickly able to complete that portion of the program. I already had coded the 'combining' of three listboxes (scripts) into one final one, where odd rows are printed out left to right, and even ones right to left (as if I were actually crocheting it). So, just have to 'put it all together' where I used the already saved scripts and the user only has to do is select the three letters (or type them in a textbox) to produce the actual final script. I am also currently working on reading the scripts (individual letter and/or all three) back in to show in a FlexGrid (or FlexgridS) what they look like. If one desires to CHANGE a letter based on the grid, I'll give them that capability. I could have used a simple database, but opted for the just as easy text files.
Thanks again for ALL of your help.
(Granddaughters arriving tomorrow...maybe I'll let THEM use it and learn how to crochet! :-))