private static void DrawNode(Tree.Node node, Graphics g, int depth, float x, float y, float imageWidth) { const int CHAR_WIDTH = 16; const int rectHeight = 20; const float distanceYBetweenNodes = (float)rectHeight * 1.5f; int rectWidth = 40; if (depth > 12) { return; //only draw to depth 12; } if (node is Tree.FuncNode) { Tree.FuncNode functionNode = node as Tree.FuncNode; rectWidth = functionNode.Function.Name.Length * CHAR_WIDTH; g.DrawRectangle(Pens.Blue, x - (rectWidth / 2), y - (rectHeight / 2), rectWidth, rectHeight); g.DrawString(functionNode.Function.Name, Font, Brushes.Blue, x - (rectWidth / 2), y - (rectHeight / 2)); int numberOfChildren = functionNode.Children.Length; float nodeSplitting = (float)(imageWidth / 2) * (float)Math.Pow(0.5, depth) * (float)1.0; for (int i = 0; i < numberOfChildren; i++) { float childX = (x - nodeSplitting) + (((float)Math.Pow(i, 0.8) * nodeSplitting * 2) / (numberOfChildren - 1)); g.DrawLine(LinePen, x, y + rectHeight / 2, childX, y + distanceYBetweenNodes - (rectHeight / 2)); DrawNode(functionNode.Children[i], g, depth + 1, childX, y + distanceYBetweenNodes, imageWidth); } } else if (node is Tree.ValueNode) { Tree.ValueNode valueNode = node as Tree.ValueNode; rectWidth = valueNode.Value.ToString().Length *CHAR_WIDTH; g.DrawRectangle(Pens.Red, x - (rectWidth / 2), y - (rectHeight / 2), rectWidth, rectHeight); g.DrawString(valueNode.Value.ToString(), Font, Brushes.Blue, x - (rectWidth / 2), y - (rectHeight / 2)); } else if (node is Tree.VariableNode) { Tree.VariableNode variableNode = node as Tree.VariableNode; rectWidth = variableNode.Variable.Name.Length * CHAR_WIDTH; g.DrawRectangle(Pens.DarkGreen, x - (rectWidth / 2), y - (rectHeight / 2), rectWidth, rectHeight); g.DrawString(variableNode.Variable.Name.ToString(), Font, Brushes.DarkGreen, x - (rectWidth / 2), y - (rectHeight / 2)); } else { throw new ApplicationException(); } }
private Tree.Node GenerateRandomNode(int depth, RandomGenerationMethod randomGenMeth) { double randType = s_Random.NextDouble(); Tree.Node node; bool generateTerminal = true; if (randomGenMeth == RandomGenerationMethod.FULL) { if (depth >= MAXFULLDEPTH) { generateTerminal = true; } else { generateTerminal = false; } } else if (randomGenMeth == RandomGenerationMethod.GROW) { if (s_Random.NextDouble() < 0.5 || depth >= MAXFULLDEPTH) { generateTerminal = true; } else { generateTerminal = false; } } else { throw new ApplicationException(); } if (generateTerminal) { if (s_Random.NextDouble() < 0.5) { int valueNum = s_Random.Next(m_Values.Length); node = new Tree.ValueNode(m_Values[valueNum]); } else { int variableNum = s_Random.Next(m_Variables.Length); node = new Tree.VariableNode(m_Variables[variableNum]); } } else { int funcNum = s_Random.Next(m_Functions.Length); if (m_Functions[funcNum].NumberOfArguments == 2) { node = new Tree.FuncNode( new Tree.Node[] { GenerateRandomNode(depth + 1, randomGenMeth), GenerateRandomNode(depth + 1, randomGenMeth) }, m_Functions[funcNum]); } else if (m_Functions[funcNum].NumberOfArguments == 4) { node = new Tree.FuncNode( new Tree.Node[] { GenerateRandomNode(depth + 1, randomGenMeth), GenerateRandomNode(depth + 1, randomGenMeth), GenerateRandomNode(depth + 1, randomGenMeth), GenerateRandomNode(depth + 1, randomGenMeth) }, m_Functions[funcNum]); } else { throw new ApplicationException(); } } node.Depth = depth; m_NodesAdded++; return(node); }