Hello,
so you don’t program and you want to be able to add color quite a bit odd but whatever I tried to orient you in the direction on the grasshopper forum.
I don’t want to give my code but I let some clues for a good samaritin !
The algorithm is quite simple
Make an image in memory (a 2D array (grey) or 3 2D array (color)
Place N (~100 to 1000) points around
Choose a first point
For all itterations (1000 to 4000)
_For all pins
___Draw a line (white or black with transparency)
___Count how much color it removes from the image
___Track this percentage of removal
_End for all pins
_Choose the line that remove the maximum of color
Repeat until the end of all itterations
I recommand to use array of double to represent image, that is far faster than windows image
Use antialising to draw the line
I make a voice recognition program to help me placing the thread. I say “Next” to the computer and it gives me the next number. It writes also the numbers on the screen. See the code
I also make GCode to drill the holes (here 200 holes code for 600 mm square panel)
20181207_200trous_600mm600mm.txt (15.7 KB)
Quite lot of work …
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.IO;
namespace LectureFichierNombres
{
public partial class Form1 : Form
{
SpeechSynthesizer synth;
IReadOnlyCollection<InstalledVoice> voices;
int voiceIndex;
public int indexOfNumber;
List<int> numbers;
SpeechRecognitionEngine recEngine;
public Form1()
{
//The voices
voiceIndex = 0;
InitializeComponent();
synth = new SpeechSynthesizer();
voices = synth.GetInstalledVoices();
foreach (InstalledVoice voice in voices)
{
this.listBoxVoices.Items.Add(voice.VoiceInfo.Name);
}
listBoxVoices.SelectedIndex = 0;
//Voic recognition
Choices commands = new Choices();
commands.Add(new String[] { "suivant", "next", "plus"});
GrammarBuilder gBuilder = new GrammarBuilder();
gBuilder.Append(commands);
Grammar gram = new Grammar(gBuilder);
recEngine = new SpeechRecognitionEngine();
recEngine.LoadGrammar(gram);
recEngine.SetInputToDefaultAudioDevice();
recEngine.SpeechRecognized += RecEngine_SpeechRecognized;
recEngine.RecognizeAsync(RecognizeMode.Multiple);
label1.Text = Properties.Settings.Default.setFilePath;
numbers = new List<int>();
PopulateNumbers();
this.FormClosing += Form1_FormClosing;
this.checkBox1.Checked = Properties.Settings.Default.setWithVoice;
SetLabels();
}
private void PopulateNumbers()
{
if (File.Exists(Properties.Settings.Default.setFilePath))
{
string[] lines = System.IO.File.ReadAllLines(Properties.Settings.Default.setFilePath);
numbers.Clear();
indexOfNumber = Properties.Settings.Default.setLastIndex ;
foreach (String line in lines)
{
int number;
if (Int32.TryParse(line, out number))
{
numbers.Add(number);
}
}
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//Save all the information concerning the session
Properties.Settings.Default.Save();
}
private void PrecIndex(bool withVoice)
{
indexOfNumber-= 1;
if (indexOfNumber >= 0 && indexOfNumber < numbers.Count)
{
if (withVoice)
synth.Speak(" "+numbers[indexOfNumber]);
SetLabels();
SaveHistory("PREV", indexOfNumber, numbers[indexOfNumber]);
}
}
private void NextIndex(bool withVoice)
{
indexOfNumber += 1;
if (indexOfNumber >=0 && indexOfNumber < numbers.Count)
{
Properties.Settings.Default.setLastIndex = indexOfNumber;
if (withVoice)
synth.Speak(" " + numbers[indexOfNumber]);
SaveHistory("NEXT", indexOfNumber, numbers[indexOfNumber]);
}
SetLabels();
}
private void RecEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result.Confidence > 0.750)
{
labelRecogniton.Text = "Je comprends " + e.Result.Confidence.ToString();
switch (e.Result.Text)
{
case "suivant": NextIndex(Properties.Settings.Default.setWithVoice); break;
case "next": NextIndex(Properties.Settings.Default.setWithVoice); break;
case "plus": NextIndex(Properties.Settings.Default.setWithVoice); break;
default:
synth.Speak("Bla Bla");
break;
};
}
else
{
labelRecogniton.Text = "Je ne comprends pas "+ e.Result.Confidence.ToString();
}
// throw new NotImplementedException();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void listBoxVoices_ControlAdded(object sender, ControlEventArgs e)
{
}
private void comboBox1_ControlAdded(object sender, ControlEventArgs e)
{
}
private void listBoxVoices_SelectedIndexChanged(object sender, EventArgs e)
{
voiceIndex = listBoxVoices.SelectedIndex;
}
private void button1_Click(object sender, EventArgs e)
{
//synth.Speak("Voix de"+ voices.ElementAt(voiceIndex).VoiceInfo.Name);
var fileContent = string.Empty;
var filePath = string.Empty;
var filePathHistory = string.Empty;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
if (filePath != null)
openFileDialog.InitialDirectory = Properties.Settings.Default.setFilePath;
openFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog.FilterIndex = 0;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
//Get the path of specified file
if (File.Exists(openFileDialog.FileName))
{
filePath = openFileDialog.FileName;
filePathHistory = filePath + ".hist";
label1.Text = filePath;
PopulateNumbers();
if (Properties.Settings.Default.setFilePath != filePath)
{
Properties.Settings.Default.setFilePath = filePath;
this.indexOfNumber = 0;
}
if (Properties.Settings.Default.setFilePathHistory != filePathHistory)
{
Properties.Settings.Default.setFilePathHistory = filePathHistory;
}
}
}
}
}
private void button2_Click(object sender, EventArgs e)
{
PrecIndex(false);
}
private void button3_Click(object sender, EventArgs e)
{
NextIndex(false);
}
private void SaveHistory(string text,int lineNumber, int pinNumber)
{
if (!File.Exists(Properties.Settings.Default.setFilePathHistory))
{
File.AppendAllText(Properties.Settings.Default.setFilePathHistory, "Direction, Line number, Pin number, Date" + Environment.NewLine);
}
File.AppendAllText(Properties.Settings.Default.setFilePathHistory, text + ", "+ lineNumber.ToString() + ", "+pinNumber.ToString()+", "+ DateTime.Now.ToString() + Environment.NewLine);
}
private void SetLabels()
{
if ((indexOfNumber - 1) >= 0 && (indexOfNumber - 1) < numbers.Count)
{
labelIndexPrec.Text = (indexOfNumber - 1).ToString();
labelNumberPrec.Text = numbers[indexOfNumber - 1].ToString();
}
else
{
labelIndexPrec.Text = "DEBUT";
labelNumberPrec.Text = "DEBUT";
}
if ((indexOfNumber) >= 0 && (indexOfNumber ) < numbers.Count)
{
labelIndexActual.Text = (indexOfNumber).ToString();
labelNumberActual.Text = numbers[indexOfNumber ].ToString();
}
else
{
labelIndexActual.Text = "?";
labelNumberActual.Text = "?";
}
if ((indexOfNumber+1) >= 0 && (indexOfNumber+1) < numbers.Count)
{
labelIndexNext.Text = (indexOfNumber+1).ToString();
labelNumberNext.Text = numbers[indexOfNumber+1].ToString();
}
else
{
labelIndexNext.Text = "FIN";
labelNumberNext.Text = "FIN";
}
}
private void Reset()
{
indexOfNumber = 0;
SetLabels();
}
private void button4_Click(object sender, EventArgs e)
{
Reset();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked) Properties.Settings.Default.setWithVoice = true;
else Properties.Settings.Default.setWithVoice = false;
}
}
}
`