public void setImage(Image img) { if (img == null) { return; } Reference.currentImage = img; pan_PuzzlePanel.Controls.Clear(); // create first puzzlepiece PuzzlePiece pp = new PuzzlePiece(); pp.Image = img; // reposition image in frame to the middle pp.Location = new Point((img.Width * Reference.Ratio - img.Width) / 2, (img.Height * Reference.Ratio - img.Height) / 2); // check size of img (SCALE?) // resize panel (3 * image size) pan_PuzzlePanel.Size = new Size(img.Width * Reference.Ratio, img.Height * Reference.Ratio); // adjust frame size adjustSize(); // add first puzzlepiece pan_PuzzlePanel.Controls.Add(pp); pan_PuzzlePanel.Refresh(); }
private void PuzzlePiece_MouseUp(object sender, MouseEventArgs mea) { if (mea == null || sender != activePuzzlePiece) { return; } // move active (currently moved) puzzlepiece to final position next to second puzzlepiece PuzzlePiece pp = this.getNearPP(); if (pp != null) { activePuzzlePiece.Location = pp.Location; activePuzzlePiece.inPosition = true; findLocation(); // recombine puzzlepieces //this.Controls.Remove(activePuzzlePiece); //this.Controls.Remove(pp); //PuzzlePiece newPp = activePuzzlePiece.Combine(pp); //newPp.MouseDown += new MouseEventHandler(this.PuzzlePiece_MouseDown); //newPp.MouseMove += new MouseEventHandler(this.PuzzlePiece_MouseMove); //newPp.MouseUp += new MouseEventHandler(this.PuzzlePiece_MouseUp); //this.Controls.Add(newPp); } clicked = false; activePuzzlePiece.BorderColor = Color.Black; activePuzzlePiece = null; }
private void PuzzlePiece_MouseDown(object sender, MouseEventArgs mea) { if (mea == null) { return; } if (mea.Button == MouseButtons.Left) { if (sender is PuzzlePiece) { // is click location inside puzzlepiece? if (((PuzzlePiece)sender).isInside(mea.Location)) { // save this position for moving MouseDownLocation = mea.Location; // save mouse down clicked = true; // set active puzzlepiece activePuzzlePiece = (PuzzlePiece)sender; movePuzzlePiece(mea.Location); } } } }
// check if splitted new puzzlepiece is big enough private bool evalPuzzlePiece(PuzzlePiece pp) { bool flag = false; // minimum pixel area if (pp.Area < Reference.minArea) { flag = true; } // area between 30% and 70% of original polygon; original == (pp1 + pp2) if (pp.Area < this.Area * Reference.minSize || pp.Area > this.Area * Reference.maxSize) { flag = true; } // width greater 8 pixel if (calcWidth(pp) < Reference.minWidth) { flag = true; } return flag; }
// calculate width of puzzlepiece private double calcWidth(PuzzlePiece pp) { double width = 0f; double a = 0, b = 0, c = 0; double mid1 = 0, mid2 = 0; // calculate centroid of polygon for (int i = 0; i < pp.PointList.Length - 1; i++) { mid1 += pp.PointList[i].X; mid2 += pp.PointList[i].Y; } mid1 /= (pp.PointList.Length - 1); mid2 /= (pp.PointList.Length - 1); // calculate a, b, c and width^2 according to equation for (int i = 0; i < pp.PointList.Length - 1; i++) { a += Math.Pow((pp.PointList[i].X - mid1), 2); b += (pp.PointList[i].X - mid1) * (pp.PointList[i].Y - mid2); c += Math.Pow((pp.PointList[i].Y - mid2), 2); } width = (2f / (pp.PointList.Length - 1)) * (a + c - Math.Sqrt(Math.Pow((a + c), 2) - 4f * ((a * c) - Math.Pow(b, 2)))); return Math.Sqrt(width); }
public bool Split(out PuzzlePiece pp1, out PuzzlePiece pp2) { // get random seed based on current time Random random = new Random(DateTime.Now.Millisecond); pp1 = new PuzzlePiece(); pp1.Bounds = this.Bounds; pp1.Image = this.Image; pp2 = new PuzzlePiece(); pp2.Bounds = this.Bounds; pp2.Image = this.Image; ArrayList list1 = new ArrayList(); ArrayList list2 = new ArrayList(); int line1, line2; // try 10 times to split this puzzlepiece for (int i = 0; i < Reference.SplitTries; i++) { // clear polygon lists list1.Clear(); list2.Clear(); // get random lines do { line1 = random.Next(this.points.Length - 1); line2 = random.Next(this.points.Length - 1); } while (line1 >= line2); // get random points on lines double offset; offset = random.NextDouble(); Point point1 = createPointOnLine(this.points[line1], this.points[line1 + 1], offset); offset = random.NextDouble(); Point point2 = createPointOnLine(this.points[line2], this.points[line2 + 1], offset); // add points clockwise to list1 list1.Add(point1); for (int j = line1 + 1; j <= line2; j++) { list1.Add(this.points[j]); } list1.Add(point2); // start point == end point list1.Add(point1); // add points to puzzlepiece and recalculate area pp1.points = (Point[])list1.ToArray(typeof(Point)); //pp1.area = pp1.calcArea(pp1.points); // add points clockwise to list2 list2.Add(point2); for (int j = line2 + 1; j < line1 + (this.points.Length); j++) { list2.Add(this.points[j % (this.points.Length - 1)]); } list2.Add(point1); // start point == end point list2.Add(point2); // add points to puzzlepiece and recalculate area pp2.points = (Point[])list2.ToArray(typeof(Point)); //pp2.area = pp2.calcArea(pp2.points); if (!(evalPuzzlePiece(pp1) || evalPuzzlePiece(pp2))) { // polygon splitting possible return true; } } // polygon splitting impossible after 10 tries pp1 = null; pp2 = null; return false; }
// calculate distance between two puzzlepieces public double Distance(PuzzlePiece pp2) { bool flag = false; // have a point in common? foreach (Point point1 in this.PointList) { foreach (Point point2 in pp2.PointList) { if (point1 == point2) { flag = true; } } } // distance between two points (left side pp2 - left side this) and (top side pp2 - top side this) if (flag) { return Math.Sqrt(Math.Pow(pp2.Left - this.Left, 2) + Math.Pow(pp2.Top - this.Top, 2)); } // no line in common else { return double.MaxValue; } }
// [WIP] recombine puzzlepieces to get rid of borders public PuzzlePiece Combine(PuzzlePiece pp) { ArrayList list = new ArrayList(); int i = -1; ArrayList points1 = new ArrayList(this.PointList); ArrayList points2 = new ArrayList(pp.PointList); list.AddRange(points1); foreach (Point point in points2) { i = list.IndexOf(point); if (i != -1) { break; } } list.InsertRange(i, points2); PuzzlePiece newPp = new PuzzlePiece(); newPp.Location = this.Location; newPp.Image = this.Image; newPp.points = (Point[])list.ToArray(typeof(Point)); return newPp; }