LAMPIRAN 1 1.1 MainForm.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using TS_Eka.Helper; namespace TS_Eka { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private void tentangPenulisToolStripMenuItem_Click(object sender, EventArgs e) { FormInfo frm = formHelper.getFormInfo(); frm.MdiParent = this; frm.Show(); } private void prosesToolStripMenuItem_Click(object sender, EventArgs e) { FormProses frm = formHelper.getFormProses(); frm.MdiParent = this; frm.Show(); } private void MainForm_Load(object sender, EventArgs e) { } } } 1.2 FormInfo.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data;
L.2
using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace TS_Eka { public partial class FormInfo : Form { public FormInfo() { InitializeComponent(); String URL = AppDomain.CurrentDomain.BaseDirectory + "Info\\tentang.html"; webBrowserInfo.Navigate(URL); } private void webBrowserInfo_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { } } } 1.3 FormProses.cs using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using TS_Eka.Class; using TS_Eka.Helper; namespace TS_Eka { public partial class FormProses : Form { public Pattern[] listPattern; public int heightMap, widthMap; private string fileName; public FormProses() {
L.3
InitializeComponent(); dgvPola.Rows.Clear(); } private void btnTambah_Click(object sender, EventArgs e) { GambarPattern myGambarPattern; OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog1.Filter = "bmp files (*.bmp)|*.bmp"; openFileDialog1.FilterIndex = 1; if (openFileDialog1.ShowDialog() == DialogResult.OK) { myGambarPattern = new GambarPattern(openFileDialog1.FileName); fileName = openFileDialog1.FileName; pbPola.Image = (Image)myGambarPattern.Gambar; txtLebarPola.Text = Convert.ToString(myGambarPattern.Lebar); txtTinggiPola.Text = Convert.ToString(myGambarPattern.Tinggi); Object[] obj = new Object[3]; obj[0] = fileName; obj[1] = txtLebarPola.Text; obj[2] = txtTinggiPola.Text; dgvPola.Rows.Add(obj); } } private void dgvPola_CellClick(object sender, DataGridViewCellEventArgs e) { int selectedRowCount = dgvPola.Rows.GetRowCount(DataGridViewElementStates.Selected); if (selectedRowCount > 0) { int row = dgvPola.SelectedRows[0].Index; string fileName = dgvPola.Rows[row].Cells[0].Value.ToString(); string lebar = dgvPola.Rows[row].Cells[1].Value.ToString(); string tinggi = dgvPola.Rows[row].Cells[2].Value.ToString(); GambarPattern myGambarPattern = new GambarPattern(fileName); pbPola.Image = (Image)myGambarPattern.Gambar; txtLebarPola.Text = lebar; txtTinggiPola.Text = tinggi; }
L.4
} private void btnProses_Click(object sender, EventArgs e) { if (txtLebarBidang.Text == "" || txtTinggiBidang.Text == "" || txtSkalaBidang.Text == "") { MessageBox.Show("Tidak boleh ada data yang kosong"); } else if (dgvPola.Rows.Count == 0) { MessageBox.Show("Pola yang digunakan harus ada"); } else { int skala = Convert.ToInt32(txtSkalaBidang.Text); listPattern = new Pattern[dgvPola.Rows.Count]; for (int i = 0; i < dgvPola.Rows.Count; i++) { string fileName = dgvPola.Rows[i].Cells[0].Value.ToString(); int lebar = Convert.ToInt32(dgvPola.Rows[i].Cells[1].Value.ToString()); int tinggi = Convert.ToInt32(dgvPola.Rows[i].Cells[2].Value.ToString()); GambarPattern myGambarPattern = new GambarPattern(fileName); Bitmap myImage = new Bitmap((Image)myGambarPattern.Gambar); GambarMatrix myMatrix = new GambarMatrix(); myMatrix.SetImage(myImage, tinggi, lebar, skala); myMatrix.TransformGambarToMatrix(); myMatrix.patternProses.fileName = fileName; listPattern[i] = myMatrix.patternProses; } Console.WriteLine("List Pattern : {0}", listPattern.Length); heightMap = Convert.ToInt32(txtTinggiBidang.Text); widthMap = Convert.ToInt32(txtLebarBidang.Text); FormOutput frm = new FormOutput(listPattern, heightMap, widthMap, skala); frm.MdiParent = this.MdiParent; this.Close(); frm.Show(); } }
L.5
private void FormProses_Load(object sender, EventArgs e) { } private void dgvPola_CellContentClick(object sender, DataGridViewCellEventArgs e) { } } } 1.4 FormOutput.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using TS_Eka.Class; namespace TS_Eka { public partial class FormOutput : Form { private Pattern[] listPattern; private Map mapHasil; private int heightMap, widthMap, skala; private Hasil hasilAkhir, hasilProses; private int counterHasil; public FormOutput() { InitializeComponent(); } public FormOutput(Pattern[] listPattern, int heightMap, int widthMap, int skala) { InitializeComponent(); this.listPattern = listPattern; this.heightMap = heightMap; this.widthMap = widthMap; this.skala = skala;
L.6
DateTime dt1, dt2; TimeSpan dtDiff1; dt1 = DateTime.Now; Map mapAwal = new Map((int)widthMap/skala, (int)heightMap/skala); Hasil hasilOptimasi = new Hasil((int)widthMap/skala, (int)heightMap/skala); hasilAkhir = new Hasil((int)widthMap / skala - 1, (int)heightMap / skala - 1); hasilAkhir.listPattern = new Pattern[listPattern.Length]; SortPattern(); //RotasiPattern(mapAwal, listPattern, 0, hasilOptimasi); hasilAkhir.mapTerbaik = MulaiProses(mapAwal, hasilOptimasi); hasilAkhir.listPatternTemp.RemoveAt(hasilAkhir.listPatternTemp.Count - 1); hasilAkhir.listPatternUsed = new Pattern[hasilAkhir.listPatternTemp.Count]; hasilAkhir.listPatternTemp.CopyTo(hasilAkhir.listPatternUsed); dt2 = DateTime.Now; dtDiff1 = dt2.Subtract(dt1); MessageBox.Show("Selesai dalam waktu " + dtDiff1.ToString(), "confirm", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1); hasilProses = hasilAkhir; Console.WriteLine("Height : {0}, Width : {1}", heightMap, widthMap); Bitmap kanvas = new Bitmap(widthMap + hasilAkhir.listPatternUsed[0].skala * 2, heightMap + hasilAkhir.listPatternUsed[0].skala * 2); pbHasil.Image = (Image)kanvas; pbHasil.Height = heightMap; pbHasil.Width = widthMap; for (int a = 0; a < hasilAkhir.listPatternUsed.Length; a++) { ShowPatternOnMap(a + 1, kanvas, hasilAkhir.mapTerbaik, hasilAkhir.listPatternUsed[a]); } DrawImageLine(kanvas, hasilAkhir.listPatternUsed[0].skala); pbHasil.Image = (Image)kanvas; } private bool PatternNgaBisaSemua(int[] ForbiddenPattern) { int counter = new int(); for (int a = 0; a < ForbiddenPattern.Length; a++) {
L.7
if (ForbiddenPattern[a].Equals(1)) { counter++; } } if (counter.Equals(ForbiddenPattern.Length)) { return true; } else { return false; } } private Map MulaiProses(Map mapAwal, Hasil hasilOptimasi) { # region variable //map terbaik untuk menyimpan satu hasil terbaik Map mapTerbaik = new Map(mapAwal.pixel.GetLength(0), mapAwal.pixel.GetLength(1)); //counter untuk menunjukkan sudah berapa kali suatu pattern yang dicoba dimasukkan ke map int counterInsertedPattern = new int(); //variabel untuk menyimpan titik2 basis pertemuan antara map dengan pattern int basisXMap, basisYMap, basisXPattern, basisYPattern; //variabel posisi di peta yang akan ditaruh isi int xMap, yMap; //variabel untuk menyimpan nilai dari suatu koordinat pada map int mapValue; //variable untuk menyimpan pattern yang sudah tidak bisa ditaruh lagi int[] ForbiddenPattern; //variable untuk cek apakah pattern masih bisa ditaruh dalam map Boolean InsertPatternBerhasil = new Boolean(); //variabel yang menunjukkan sudah berapa banyak pattern ada di map int counterPattern = new int(); # endregion #region inisialisasi ForbiddenPattern = new int[listPattern.Length]; counterPattern = 0; #endregion //cek jika pattern semua sudah tidak bisa maka stop proses while (PatternNgaBisaSemua(ForbiddenPattern).Equals(false)) {
L.8
//looping satu set pattern for (int patternKe = 0; patternKe < listPattern.Length; patternKe++) { //jika objek pertama kali maka taruh di paling pojok kiri atas //else cari posisi yang terbaik if (counterPattern.Equals(0)) { #region variable //variabel untuk koordinat pada map yang akan diproses int posX, posY; //variabel local untuk map terbaik(yang akan dicari dari proses berikut) Map mapTerbaikLocal = CopyMap(mapTerbaik); //variabel untuk menampung sementara map yang sedang diproses Map mapProses; #endregion #region inisialisasi counterInsertedPattern = 0; hasilAkhir.listPatternTemp.Add(CopyPattern(listPattern[0])); #endregion #region rotasi & translasi (Proses) //rotasi pattern for (int derajatRotasi = 0; derajatRotasi < 360; derajatRotasi = derajatRotasi + 90) { //reset map yang diproses dengan mapTerbaik mapProses = CopyMap(mapTerbaik); //rotasi pattern sebanyak derajatRotasi //WARNING fungsi dibawah ini belum menggunakan parameter dari derajat rotasi tetapi langsung dirotasi sebanyak 90 derajat listPattern[0].Rotasi(); #region taruh isi dari pattern yang diproses ke map //taruh 'isi' for (int a = 0; a < listPattern[0].isi.Count; a++) { posX = ((Position)listPattern[0].isi[a]).x - 1; posY = ((Position)listPattern[0].isi[a]).y - 1; mapProses.pixel[posX, posY] = 1; } #endregion #region taruh samping pattern yang sedang diproses ke map //taruh 'samping'
L.9
for (int a = 0; a < listPattern[0].samping.Count; a++) { posX = ((Position)listPattern[0].samping[a]).x - 1; posY = ((Position)listPattern[0].samping[a]).y - 1; if (posX >= 0 && posY >= 0) { //masukkin ke pixel peta mapProses.pixel[posX, posY] = 1005; //masukkin ke 'samping' peta mapProses.tambahSamping(posX, posY); } } //sorting samping //mapProses.sortingSamping(); #endregion #region cek mapTerbaikLocal perlu diupdate nga //jika pattern sudah selesai ditaruh ke map cek di list apakah terbaik //jika pattern pertama kali maka simpan langsung atau terbaik maka disimpan if (counterInsertedPattern == 0 || mapProses.samping.Count < mapTerbaikLocal.samping.Count) { mapTerbaikLocal = CopyMap(mapProses); counterInsertedPattern++; hasilAkhir.listPattern[0] = CopyPattern(listPattern[0]); hasilAkhir.listPatternTemp[0] = CopyPattern(listPattern[0]); } //jika tidak maka nga usah diapa apain # endregion } #endregion #region update mapTerbaik dengan mapTerbaikLocal mapTerbaik = CopyMap(mapTerbaikLocal); counterPattern++; //reserved element dalam listPatternTemp untuk proses berikutnya //mencegah jika pattern inputan hanya 1 if (listPattern.Length > 1)
L.10
{ hasilAkhir.listPatternTemp.Add(CopyPattern(listPattern[1])); } else { hasilAkhir.listPatternTemp.Add(CopyPattern(listPattern[0])); } #endregion } else { //jika pattern sudah dilarang berarti nga usa dicoba dimasukkin if (ForbiddenPattern[patternKe].Equals(0)) { #region variable //variabel local untuk map terbaik(yang akan dicari dari proses berikut) Map mapTerbaikLocal = CopyMap(mapTerbaik); //variabel untuk menampung sementara map yang sedang diproses Map mapProses; #endregion #region inisialisasi counterInsertedPattern = 0; //reset InsertPatternBerhasil InsertPatternBerhasil = false; #endregion #region rotasi & translasi (proses looping) //rotasi pattern, untuk setiap pergerakan coba translasi pada setiap kemungkinan for (int derajatRotasi = 0; derajatRotasi < 360; derajatRotasi = derajatRotasi + 90) { //rotasi pattern sebanyak derajatRotasi //WARNING fungsi dibawah ini belum menggunakan parameter dari derajat rotasi tetapi langsung dirotasi sebanyak 90 derajat listPattern[patternKe].Rotasi(); #region transalasi //2 loop berikut untuk translasi //loop list samping map for (int sampingMap = 0; sampingMap < mapTerbaik.samping.Count; sampingMap++) { //get basis posisi X,Y 'samping' pada peta
L.11
basisXMap = ((Position)mapTerbaik.samping[sampingMap]).x; basisYMap = ((Position)mapTerbaik.samping[sampingMap]).y; //untuk setiap titik pada list samping map dicek juga ke setiap isi dari pattern for (int isiPatternBasis = 0; isiPatternBasis < listPattern[patternKe].isi.Count; isiPatternBasis++) { //reset map yang diproses dengan map terbaik mapProses = CopyMap(mapTerbaik); //get basis dari pattern basisXPattern = ((Position)listPattern[patternKe].isi[isiPatternBasis]).x; basisYPattern = ((Position)listPattern[patternKe].isi[isiPatternBasis]).y; #region try insert isi ke map //untuk setiap 'isi' di pattern taruh di 'samping' map for (int isiPattern = 0; isiPattern < listPattern[patternKe].isi.Count; isiPattern++) { //cari posisi peletakan 'isi' pada peta xMap = basisXMap - basisXPattern + ((Position)listPattern[patternKe].isi[isiPattern]).x; yMap = basisYMap - basisYPattern + ((Position)listPattern[patternKe].isi[isiPattern]).y; //'isi' harus berada di dalam batas map if (xMap >= 0 && yMap >= 0 && xMap < mapProses.pixel.GetLength(0) && yMap < mapProses.pixel.GetLength(1)) { mapValue = mapProses.pixel[xMap, yMap]; //'isi' pattern berbenturan dengan 'isi' map (pattern yang sudah ditaruh) if (mapValue > 0 && mapValue < 1000) { goto finish; } //'isi' berada di daerah kosong else if (mapValue == 0) { //masukkin langsung mapProses.pixel[xMap, yMap] = counterPattern + 1; //patternKe+1; //patternKe+1 merupakan nilai penanda saja di peta
L.12
} //'isi' pattern berada di 'samping' map else if (mapValue >= 1000) { //ganti 'samping' di map jadi 'isi' mapProses.pixel[xMap, yMap] = counterPattern + 1; //patternKe+1; //hapus posisi 'samping' dari daftar mapProses.hapusSamping(xMap, yMap); } } else { //isi berada di luar map goto finish; } } #endregion # region taruh samping dari pattern yang sedang diproses ke map //jika isi pattern bisa diletakkan semua maka //untuk setiap 'samping' pattern letakkan di map for (int sampingPatternCurr = 0; sampingPatternCurr < listPattern[patternKe].samping.Count; sampingPatternCurr++) { xMap = basisXMap - basisXPattern + ((Position)listPattern[patternKe].samping[sampingPatternCurr]).x; yMap = basisYMap - basisYPattern + ((Position)listPattern[patternKe].samping[sampingPatternCurr]).y; if (xMap >= 0 && yMap >= 0 && xMap < mapProses.pixel.GetLength(0) && yMap < mapProses.pixel.GetLength(1)) { mapValue = mapProses.pixel[xMap, yMap]; //'samping' pattern harus berupa di daerah kosong if (mapValue == 0) { mapProses.pixel[xMap, yMap] = (counterPattern + 1) * 1000 + 5; //(patternKe+1) * 10 + 5; mapProses.tambahSamping(xMap, yMap); } } }
L.13
//sorting samping //mapProses.sortingSamping(); # endregion #region cek mapTerbaikLocal perlu diupdate nga //jika pattern sudah selesai ditaruh ke map cek di list apakah terbaik //jika pattern pertama kali maka simpan langsung atau terbaik maka disimpan if (counterInsertedPattern == 0 || (mapProses.luas() <= mapTerbaikLocal.luas() && mapProses.samping.Count < mapTerbaikLocal.samping.Count)) { mapTerbaikLocal = CopyMap(mapProses); counterInsertedPattern++; //21/05/2006 update list pattern terbaik hasilAkhir.listPattern[patternKe] = CopyPattern(listPattern[patternKe]); //28/05/2006 hasilAkhir.listPatternTemp[counterPattern] = CopyPattern(listPattern[patternKe]); //jika ada pattern satu aja yang berhasil ditaruh maka set insertpatternberhasil = true InsertPatternBerhasil = true; } //jika tidak maka nga usah diapa apain # endregion finish: ; } } #endregion } #endregion #region update mapTerbaik dengan mapTerbaikLocal atau forbiddenPattern if (InsertPatternBerhasil.Equals(true)) { mapTerbaik = CopyMap(mapTerbaikLocal); counterPattern++; //reserved tempat dalam array list untuk pattern berikutnya
L.14
hasilAkhir.listPatternTemp.Add(CopyPattern(listPattern[patternKe])); } else { ForbiddenPattern[patternKe] = 1; } #endregion } } //selesai proses diatas berarti sudah didapatkan posisi terbaik dari sebanyak patternKe } } return mapTerbaik; } private Position ScanMatrixHasil(Map mapCurr, int noPattern) { //scan matrix map per baris, kolom //sampai ketemu titik pattern sebagai patokan dalam matrix Position myPosition = new Position(); for (myPosition.y = 0; myPosition.y < mapCurr.pixel.GetLength(1); myPosition.y++) { for (myPosition.x = 0; myPosition.x < mapCurr.pixel.GetLength(0); myPosition.x++) { if (mapCurr.pixel[myPosition.x, myPosition.y] == noPattern) { goto finishScanMap; } } } finishScanMap: ; return myPosition; }
private Position ScanMatrixGambar(int[,] matrixWarna, int[,] matrixPutih) { //Scan matrix per baris,kolom
L.15
//sampai ketemu titik terkecil dari region Position myPosition = new Position(); int a, b; for (b = 0; b < matrixWarna.GetLength(1); b++) { for (a = 0; a < matrixWarna.GetLength(0); a++) { if ((float)matrixWarna[a, b] / (float)(matrixWarna[a, b] + matrixPutih[a, b]) > 0.5) { myPosition.x = a; myPosition.y = b; return myPosition; } } } return myPosition; } private Position ScanFirstPixelInsertToRegion(Position myPosition, Pattern myPattern) { int a, b; //FUNGSI MENEMUKAN PIXEL YANG MASUK KE REGION myPosition //scan perbaris, kolom untuk menemukan pixel pertama yang masuk ke region patokan Bitmap myImage = new Bitmap(myPattern.fileName); //rotasi image int banyakRotasi; myPattern.derajatRotasi = myPattern.derajatRotasi % 360; banyakRotasi = (int)decimal.Divide(myPattern.derajatRotasi, 90); for (a = 0; a < banyakRotasi; a++) { myImage.RotateFlip(RotateFlipType.Rotate90FlipNone); } int yAwal = 0, yAkhir = 0, xAwal = 0, xAkhir = 0; float regX, regY; int posX, posY; int jmlRegionX, jmlRegionY; int lebar, tinggi;
L.16
//ambil batas2 gambar
for (a = 0; a < myImage.Height; a++) { for (b = 0; b < myImage.Width; b++) { if (myImage.GetPixel(b, a).ToArgb() != Color.White.ToArgb()) { yAwal = a; goto finishGetTop; } } } finishGetTop: ; for (a = myImage.Height - 1; a >= 0; a--) { for (b = 0; b < myImage.Width; b++) { if (myImage.GetPixel(b, a).ToArgb() != Color.White.ToArgb()) { yAkhir = a; goto finishGetBottom; } } } finishGetBottom: ; for (a = 0; a < myImage.Width; a++) { for (b = yAwal; b <= yAkhir; b++) { if (myImage.GetPixel(a, b).ToArgb() != Color.White.ToArgb()) { xAwal = a; goto finishGetLeft; } } } finishGetLeft: ; for (a = myImage.Width - 1; a >= xAwal; a--)
L.17
{ for (b = yAwal; b <= yAkhir; b++) { if (myImage.GetPixel(a, b).ToArgb() != Color.White.ToArgb()) { xAkhir = a; goto finishGetRight; } } } finishGetRight: ; //inisialisasi matrix jmlRegionX = (int)Math.Round((decimal)myPattern.lebar / myPattern.skala, 0); jmlRegionY = (int)Math.Round((decimal)myPattern.tinggi / myPattern.skala, 0); lebar = xAkhir - xAwal + 1; tinggi = yAkhir - yAwal + 1; //SCAN GAMBAR for (posY = yAwal; posY <= yAkhir; posY++) { for (posX = xAwal; posX <= xAkhir; posX++) { regY = (((float)posY - (float)yAwal) * (float)jmlRegionY) / (float)tinggi; //-1 untuk pixel paling terakhir if (regY == (float)jmlRegionY) regY = regY - 1; //pembulatan ke bawah regY = (float)Decimal.Truncate((decimal)regY); regX = (((float)posX - (float)xAwal) * (float)jmlRegionX) / (float)lebar; //-1 untuk pixel terakhir if (regX == (float)jmlRegionX) regX = regX - 1; //pembulatan ke bawah regX = (float)Decimal.Truncate((decimal)regX); if ((int)regY == myPosition.y && (int)regX == myPosition.x) { myPosition.x = posX; myPosition.y = posY; return myPosition; }
L.18
} } return myPosition; } private void ShowPatternOnMap(int noPattern, Bitmap kanvasCurr, Map mapCurr, Pattern patCurr) { Position myPosition, baseGambar, baseHasil; int xPic, yPic; int xKanvas, yKanvas; int skala = patCurr.skala; //set image Bitmap myImage = new Bitmap(patCurr.fileName); //PERSIAPIN IMAGE ASLI //rotasi image int banyakRotasi; patCurr.derajatRotasi = patCurr.derajatRotasi % 360; banyakRotasi = (int)decimal.Divide(patCurr.derajatRotasi, 90); for (int a = 0; a < banyakRotasi; a++) { myImage.RotateFlip(RotateFlipType.Rotate90FlipNone); } //PROSES MATRIX HASIL baseHasil = ScanMatrixHasil(mapCurr, noPattern); //PROSES GAMBAR //Ambil region terkecil dari pattern yang menandakan //bahwa itu adalah patokan dari gambar matrix //ini salah nih // myPosition = patCurr.CekFirstRegion(); GambarMatrix myMatrix = new GambarMatrix(); myMatrix.SetImage(myImage, patCurr.tinggi, patCurr.lebar, patCurr.skala); myMatrix.TransformGambarToMatrix(); myPosition = ScanMatrixGambar(myMatrix.matrixWarna, myMatrix.matrixPutih); //scan perbaris, kolom //sampai menemukan pixel pertama yang masuk ke region terkecil baseGambar = ScanFirstPixelInsertToRegion(myPosition, patCurr); //PROSES TRANSFER PIXEL //scan gambar per baris, kolom
L.19
//pindahin semua warna bukan putih dari image ke kanvas for (yPic = 0; yPic < myImage.Height; yPic++) { for (xPic = 0; xPic < myImage.Width; xPic++) { if (myImage.GetPixel(xPic, yPic).ToArgb() != Color.White.ToArgb()) { xKanvas = (baseHasil.x + 1) * skala - baseGambar.x + xPic;//+100; yKanvas = (baseHasil.y + 1) * skala - baseGambar.y + yPic;//+100; kanvasCurr.SetPixel(xKanvas, yKanvas, myImage.GetPixel(xPic, yPic)); } } } } private void ShowMap(Map mapCurr) { } private Pattern CopyPattern(Pattern patternAsli) { int a, x, y; Pattern patternHasil = new Pattern(); //copy isi for (a = 0; a < patternAsli.isi.Count; a++) { x = ((Position)patternAsli.isi[a]).x; y = ((Position)patternAsli.isi[a]).y; patternHasil.TambahIsi(x, y); } //copy samping for (a = 0; a < patternAsli.samping.Count; a++) { x = ((Position)patternAsli.samping[a]).x; y = ((Position)patternAsli.samping[a]).y; patternHasil.TambahSamping(x, y); } //copy derajat rotasi patternHasil.derajatRotasi = patternAsli.derajatRotasi; //copy nama file
L.20
patternHasil.fileName = patternAsli.fileName; //copy tinggi lebar dan skala patternHasil.tinggi = patternAsli.tinggi; patternHasil.lebar = patternAsli.lebar; patternHasil.skala = patternAsli.skala; return patternHasil; } private Map CopyMap(Map mapAsli) { /// <summary> /// Mengcopy suatu map /// int a, b, x, y; Map mapHasil = new Map(mapAsli.pixel.GetLength(0), mapAsli.pixel.GetLength(1)); // copy list 'isi' for (a = 0; a < mapAsli.samping.Count; a++) { x = ((Position)(mapAsli.samping[a])).x; y = ((Position)(mapAsli.samping[a])).y; mapHasil.tambahSamping(x, y); } //copy list 'samping' for (a = 0; a < mapAsli.pixel.GetLength(0); a++) { for (b = 0; b < mapAsli.pixel.GetLength(1); b++) { mapHasil.pixel[a, b] = mapAsli.pixel[a, b]; } } return mapHasil; } private void RotasiPattern(Map mapPrev, Pattern[] patternPrev, int patternKe, Hasil hasilOptimasi) { int a; if (patternKe == patternPrev.Length) {
L.21
PutFirstPattern(mapPrev, patternPrev, hasilOptimasi); } else { for (a = 0; a < 4; a++) { patternPrev[patternKe].Rotasi(); RotasiPattern(mapPrev, patternPrev, patternKe + 1, hasilOptimasi); } } } private void DrawImageLine(Bitmap kanvasCurr, int skala) { //gambar line atas dan bawah for (int a = 0; a < kanvasCurr.Width; a++) { kanvasCurr.SetPixel(a, skala, Color.Black); kanvasCurr.SetPixel(a, kanvasCurr.Height - skala, Color.Black); } //gambar line kiri dan kanan for (int a = 0; a < kanvasCurr.Height; a++) { kanvasCurr.SetPixel(skala, a, Color.Black); kanvasCurr.SetPixel(kanvasCurr.Width - skala, a, Color.Black); } } private void PutFirstPattern(Map mapPrev, Pattern[] patternPrev, Hasil hasilOptimasi) { int a; int posX, posY; Pattern[] patternNext = new Pattern[patternPrev.Length - 1]; Pattern patternCurr; patternCurr = CopyPattern(patternPrev[0]); for (a = 0; a < patternNext.Length; a++) { patternNext[a] = CopyPattern(patternPrev[a + 1]); } Map mapCurr = CopyMap(mapPrev); for (a = 0; a < patternCurr.isi.Count; a++) {
L.22
posX = ((Position)patternCurr.isi[a]).x - 1; posY = ((Position)patternCurr.isi[a]).y - 1; mapCurr.pixel[posX, posY] = patternPrev.Length; } for (a = 0; a < patternCurr.samping.Count; a++) { posX = ((Position)patternCurr.samping[a]).x - 1; posY = ((Position)patternCurr.samping[a]).y - 1; if (posX >= 0 && posY >= 0) { mapCurr.pixel[posX, posY] = (patternPrev.Length * 10) + 5; mapCurr.tambahSamping(posX, posY); } } ProsesOptimasi(mapCurr, patternNext, hasilOptimasi); } private void ProsesOptimasi(Map mapPrev, Pattern[] patternPrev, Hasil hasilOptimasi) { if (patternPrev.Length == 0) { hasilOptimasi.Add(mapPrev, listPattern); } else { int basisXMap, basisYMap, basisXPattern, basisYPattern; int xMap, yMap, mapValue; int a, b, c; Pattern[] patternNext = new Pattern[patternPrev.Length - 1]; Pattern patternCurr = CopyPattern(patternPrev[0]); for (a = 0; a < patternNext.Length; a++) { patternNext[a] = CopyPattern(patternPrev[a + 1]); } for (a = 0; a < mapPrev.samping.Count; a++) { Map mapCurr; basisXMap = ((Position)mapPrev.samping[a]).x; basisYMap = ((Position)mapPrev.samping[a]).y;
L.23
for (b = 0; b < patternCurr.isi.Count; b++) { mapCurr = CopyMap(mapPrev); basisXPattern = ((Position)patternCurr.isi[b]).x; basisYPattern = ((Position)patternCurr.isi[b]).y; for (c = 0; c < patternCurr.isi.Count; c++) { xMap = basisXMap - basisXPattern + ((Position)patternCurr.isi[c]).x; yMap = basisYMap - basisYPattern + ((Position)patternCurr.isi[c]).y; if (xMap >= 0 && yMap >= 0 && xMap < mapCurr.pixel.GetLength(0) && yMap < mapCurr.pixel.GetLength(1)) { mapValue = mapCurr.pixel[xMap, yMap]; if (mapValue > 0 && mapValue < 10) { goto finish; } else if (mapValue == 0) { mapCurr.pixel[xMap, yMap] = patternPrev.Length; } else if (mapValue >= 10) { mapCurr.pixel[xMap, yMap] = patternPrev.Length; mapCurr.hapusSamping(xMap, yMap); } } else { goto finish; } } for (c = 0; c < patternCurr.samping.Count; c++) { xMap = basisXMap - basisXPattern + ((Position)patternCurr.samping[c]).x; yMap = basisYMap - basisYPattern + ((Position)patternCurr.samping[c]).y; if (xMap >= 0 && yMap >= 0 && xMap < mapCurr.pixel.GetLength(0) && yMap < mapCurr.pixel.GetLength(1)) { mapValue = mapCurr.pixel[xMap, yMap];
L.24
if (mapValue == 0) { mapCurr.pixel[xMap, yMap] = (patternPrev.Length * 10) * 5; mapCurr.tambahSamping(xMap, yMap); } } } ProsesOptimasi(mapCurr, patternNext, hasilOptimasi); finish: ; } } } } private void SortPattern() { //sorting di bawah ini adalah bubble sort //Descending Pattern tmpPattern = new Pattern(); int i, j, banyakPattern; banyakPattern = listPattern.Length; for (i = 1; i <= banyakPattern - 1; i++) { for (j = banyakPattern - 1; j >= i; j--) { if (listPattern[j - 1].isi.Count < listPattern[j].isi.Count) { tmpPattern = listPattern[j - 1]; listPattern[j - 1] = listPattern[j]; listPattern[j] = tmpPattern; } } } } private void FormOutput_Load(object sender, EventArgs e) { } }
L.25
} 1.5 Program.cs g System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace TS_Eka { static class Program { /// <summary> /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } } } 1.6 formHelper.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; namespace TS_Eka.Helper { public class formHelper { private static FormInfo frmInfo; private static FormProses frmProses; private static bool isCanBeUsed(Form frm) { return frm == null || frm.IsDisposed; } public static FormInfo getFormInfo() { return isCanBeUsed(frmInfo) ? (frmInfo = new FormInfo()) : frmInfo; }
L.26
public static FormProses getFormProses() { return isCanBeUsed(frmProses) ? (frmProses = new FormProses()) : frmProses; } } } 1.7 Position.cs using System; namespace TS_Eka.Class { public struct Position { private int xVal; private int yVal; public int x { get { return xVal; } set { xVal = value; } } public int y { get { return yVal; } set { yVal = value; } } } } 1.8 Pattern.cs using System; using System.Collections; namespace TS_Eka.Class { public class Pattern { public void TambahIsi(int x, int y) { /// <summary> /// Method untuk menambah 'isi' suatu pattern /// Position posTmp = new Position(); posTmp.x = x;
L.27
posTmp.y = y; isi.Add(posTmp); } public void TambahSamping(int x, int y) { /// <summary> /// Method untuk menambah 'samping' suatu pattern /// Position posTmp = new Position(); posTmp.x = x; posTmp.y = y; samping.Add(posTmp); } public void GenerateSamping() { /// <summary> /// Method untuk menghasilkan list 'samping' dari list 'isi' /// Digunakan setelah input gambar yang hanya menghasilkan 'isi' tetapi /// 'samping'nya harus digenerate /// int a, b, c; int x, y; //cek pixel disekitar 'isi' jika masih kosong jadikan samping for (a = 0; a < isi.Count; a++) { for (b = -1; b <= 1; b++) { for (c = -1; c <= 1; c++) { x = ((Position)isi[a]).x + b; y = ((Position)isi[a]).y + c; //jika posisi tersebut masih kosong //maka ditambah 'samping' if (CekNilaiPosisi(x, y) == 0) { TambahSamping(x, y); } } } } }
L.28
public void Rotasi() { /// <summary> /// Method untuk merotasi suatu pattern yang akan berakibat merubah /// posisi dalam list 'isi' dan list 'samping' /// int a; int lebar; ArrayList isiTmp = new ArrayList(); ArrayList sampingTmp = new ArrayList(); Position posTmp = new Position(); //tentukan tinggi dan lebar dari 'isi' lebar = 0; for (a = 0; a < isi.Count; a++) { if (lebar < ((Position)isi[a]).y) { lebar = ((Position)isi[a]).y; } } //rotasi 'isi' pattern for (a = 0; a < isi.Count; a++) { posTmp.y = ((Position)isi[a]).x; posTmp.x = lebar + 1 - ((Position)isi[a]).y; isiTmp.Add(posTmp); } //tentukan tinggi dan lebar dari 'samping' lebar = 0; for (a = 0; a < samping.Count; a++) { if (lebar < ((Position)samping[a]).y) { lebar = ((Position)samping[a]).y; } } //rotasi 'samping' pattern
L.29
for (a = 0; a < samping.Count; a++) { posTmp.y = ((Position)samping[a]).x; posTmp.x = lebar - ((Position)samping[a]).y; sampingTmp.Add(posTmp); } //hapus semua isi isi.Clear(); samping.Clear(); //copy reference dari tmp isi = isiTmp; samping = sampingTmp; derajatRotasi = derajatRotasi + 90; } private int CekNilaiPosisi(int x, int y) { /// <summary> /// Method untuk mencari apakah suatu posisi sudah ada dalam /// list 'samping' atau list 'isi' /// /// //CekNilaiPosisi //jika posisi (x,y) sudah ada dalam list 'isi' atau 'samping' maka bernilai 0 //yang berarti posisi tersebut sudah ditempati int a; //cek list 'isi' for (a = 0; a < isi.Count; a++) { if (((Position)isi[a]).x == x && ((Position)isi[a]).y == y) { return 1; } } //cek list 'samping for (a = 0; a < samping.Count; a++) { if (((Position)samping[a]).x == x && ((Position)samping[a]).y == y) { return 1;
L.30
} } return 0; } private int CekLebarMatrix() { int a; int lebar = 0; for (a = 0; a < isi.Count; a++) { if (lebar < ((Position)isi[a]).x) { lebar = ((Position)isi[a]).x; } } return lebar; } private int CekTinggiMatrix() { int a; int tinggi = 0; for (a = 0; a < isi.Count; a++) { if (tinggi < ((Position)isi[a]).y) { tinggi = ((Position)isi[a]).y; } } return tinggi; } public Position CekFirstRegion() { //Fungsi untuk mengecek region mana yang terkecil dari seluruh region yang ada //deklarasi int a, nilai; Position myPosition = new Position(); //inisialisasi
L.31
int lebarMatrixIsi = CekLebarMatrix(); myPosition.x = lebarMatrixIsi; myPosition.y = CekTinggiMatrix(); for (a = 0; a < isi.Count; a++) { nilai = ((Position)isi[a]).x + ((Position)isi[a]).y * lebarMatrixIsi; if (nilai < (myPosition.x + myPosition.y * lebarMatrixIsi)) { myPosition.x = ((Position)isi[a]).x; myPosition.y = ((Position)isi[a]).y; } } return myPosition; } public ArrayList isi = new ArrayList(); public ArrayList samping = new ArrayList(); public String fileName; public int derajatRotasi; public int tinggi, lebar, skala; } } 1.9 Map.cs using System; using System.Collections; namespace TS_Eka.Class { public class Map { public Map(int lengthX, int lengthY) { //tentukan besar dari matrix pixel pixel = new int[lengthX, lengthY]; } public void tambahSamping(int x, int y) { /// <summary> /// Method untuk menambah 'samping' dalam list samping /// Position posTmp = new Position();
L.32
posTmp.x = x; posTmp.y = y; samping.Add(posTmp); } public void hapusSamping(int x, int y) { /// <summary> /// Method untuk menghapus posisi x,y dalam list 'samping' /// int a; for (a = 0; a < samping.Count; a++) { if (((Position)samping[a]).x == x && ((Position)samping[a]).y == y) { samping.RemoveAt(a); goto finish; } } finish: ; } public int luas() { /// <summary> /// Mehtod untuk mencari luas dengan pendekatan 'persegi' /// pada pattern yang telah terpetakan dalam map ///
//Cari panjang dan lebar //Scan dari kanan dan bawah, ketika ada pixel yang mengandung isi //tetapkan sebagai panjang/lebar int a, b; int panjang, lebar; panjang = 0; lebar = 0; for (a = pixel.GetLength(0) - 1; a >= 0; a--) { for (b = pixel.GetLength(1) - 1; b >= 0; b--) { if (pixel[a, b] > 0 && pixel[a, b] < 10) {
L.33
panjang = a; goto CariLebar; } } } CariLebar: for (a = pixel.GetLength(1) - 1; a >= 0; a--) { for (b = 0; b < panjang; b++) { if (pixel[b, a] > 0 && pixel[b, a] < 10) { lebar = a; goto CariLuas; } } } CariLuas: return ((panjang + 1) * (lebar + 1)); } public void sortingSamping() { samping.Sort(); } public int[,] pixel; public ArrayList samping = new ArrayList(); } } 1.10 Hasil.cs using System; using System.Collections; namespace TS_Eka.Class { public class Hasil { public Hasil(int lengthX, int lengthY) { //tentukan besar dari matrix dalam object map mapTerbaik = new Map(lengthX, lengthY); }
L.34
public void Add(Map hasilCurr, Pattern[] patternCurr) { /// <summary> /// Method untuk menambahkan hasil dari suatu proses ke dalam list hasil /// // map yang dimasukkan hanya yang belum ada dalam list //cek apakah map sudah ada di hasil //jika belum ada berarti masukkan ke hasil if (CompareMap(hasilCurr, listHasil) == false) { //masukkin ke list hasil listHasil.Add(hasilCurr); //cek apakah luas map lebih kecil dari luas terbaik //jika lebih kecil maka update mapTerbaik if (hasilCurr.luas() < mapTerbaik.luas() || mapTerbaik.luas() == 1) { //update mapTerbaik mapTerbaik = CopyMap(hasilCurr); //update list terbaik listPattern = new Pattern[patternCurr.Length]; for (int a = 0; a < patternCurr.Length; a++) { listPattern[a] = CopyPattern(patternCurr[a]); } } } } private Map CopyMap(Map mapAsli) { /// <summary> /// Method untuk mengcopy object map /// int a, b, x, y; Map mapHasil = new Map(mapAsli.pixel.GetLength(0), mapAsli.pixel.GetLength(1)); //copy samping for (a = 0; a < mapAsli.samping.Count; a++)
L.35
{ x = ((Position)(mapAsli.samping[a])).x; y = ((Position)(mapAsli.samping[a])).y; mapHasil.tambahSamping(x, y); } //copy isi for (a = 0; a < mapAsli.pixel.GetLength(0); a++) { for (b = 0; b < mapAsli.pixel.GetLength(1); b++) { mapHasil.pixel[a, b] = mapAsli.pixel[a, b]; } } return mapHasil; } private Pattern CopyPattern(Pattern patternAsli) { int a, x, y; Pattern patternHasil = new Pattern(); //copy isi for (a = 0; a < patternAsli.isi.Count; a++) { x = ((Position)patternAsli.isi[a]).x; y = ((Position)patternAsli.isi[a]).y; patternHasil.TambahIsi(x, y); } //copy samping for (a = 0; a < patternAsli.samping.Count; a++) { x = ((Position)patternAsli.samping[a]).x; y = ((Position)patternAsli.samping[a]).y; patternHasil.TambahSamping(x, y); } //copy derajat rotasi patternHasil.derajatRotasi = patternAsli.derajatRotasi; //copy nama file patternHasil.fileName = patternAsli.fileName; //copy tinggi lebar dan skala
L.36
patternHasil.tinggi = patternAsli.tinggi; patternHasil.lebar = patternAsli.lebar; patternHasil.skala = patternAsli.skala; return patternHasil; } private Boolean CompareMap(Map mapCurr, ArrayList listMap) { /// <summary> /// Method untuk membandingkan kesamaan dua map /// int a, b, c; //jika list masih kosong if (listMap.Count == 0) { return false; } else { //untuk setiap map dalam list map bandingkan dengan mapCurr for (a = 0; a < listMap.Count; a++) { //bandingkan setiap pixel pada kedua map //jika ada satu pixel aja yang nga sama maka map berbeda for (b = 0; b < mapCurr.pixel.GetLength(0); b++) { for (c = 0; c < mapCurr.pixel.GetLength(1); c++) { if (mapCurr.pixel[b, c] != ((Map)listMap[a]).pixel[b, c]) { goto NextMap; } } } return true; NextMap: ; } } return false; } public ArrayList listHasil = new ArrayList(); public Map mapTerbaik;
L.37
public Pattern[] listPattern; //28/05/2006 public ArrayList listPatternTemp = new ArrayList(); public Pattern[] listPatternUsed; } } 1.11 Class Gambarpattern.cs using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; namespace TS_Eka.Class { public class GambarPattern { public GambarPattern(String fileName) { // // TODO: Add constructor logic here // xAwal = 0; xAkhir = 0; yAwal = 0; yAkhir = 0; myGambar = new Bitmap(fileName); yAwal = GetTop(); yAkhir = GetBottom(); xAwal = GetLeft(); xAkhir = GetRight(); } public Bitmap Gambar { get { return myGambar; } } public int Lebar
L.38
{ get { return xAkhir - xAwal; } } public int Tinggi { get { return yAkhir - yAwal; } } private int GetTop() { /// <summary> /// Mencari batas atas gambar /// int a, b; for (a = 0; a < myGambar.Height; a++) { for (b = 0; b < myGambar.Width; b++) { if (myGambar.GetPixel(b, a).ToArgb() != Color.White.ToArgb()) { return a; } } } return a; } private int GetBottom() { /// <summary> /// Mencari batas bawah gambar /// int a, b; for (a = myGambar.Height - 1; a >= yAwal; a--)
L.39
{ for (b = 0; b < myGambar.Width; b++) { if (myGambar.GetPixel(b, a).ToArgb() != Color.White.ToArgb()) { return a; } } } return a; } private int GetLeft() { /// <summary> /// Mencari batas kiri gambar /// int a, b; for (a = 0; a < myGambar.Width; a++) { // perubahan 25 jan 2006 // for(b=xAwal; b<=yAkhir; b++) for (b = yAwal; b <= yAkhir; b++) { if (myGambar.GetPixel(a, b).ToArgb() != Color.White.ToArgb()) { return a; } } } return a; } private int GetRight() { /// <summary> /// Mencari batas kanan gambar /// int a, b; for (a = myGambar.Width - 1; a >= xAwal; a--) {
L.40
for (b = yAwal; b <= yAkhir; b++) { if (myGambar.GetPixel(a, b).ToArgb() != Color.White.ToArgb()) { return a; } } } return a; } private Bitmap myGambar; private int yAwal, yAkhir, xAwal, xAkhir; } } 1.12 Class GambarMatrix.cs using System; using System.Collections; using System.Drawing; namespace TS_Eka.Class { public class GambarMatrix { public void SetImage(Bitmap patternImage, int tinggi, int lebar, int skala) { /// <summary> /// inisialisasi gambar, tinggi, lebar, skala /// patternGambar = new Bitmap(patternImage); tGambar = tinggi; lGambar = lebar; sGambar = skala; } public void TransformGambarToMatrix() { /// <summary> /// Merubah gambar menjadi matrix (matrix warna dan matrix putih) /// yang mewakili banyaknya pixel dari suatu region/daerah matrix /// float regX, regY;
L.41
int posX, posY; int jmlRegionX, jmlRegionY; int lebar, tinggi; //ambil batas2 gambar yAwal = GetTop(); yAkhir = GetBottom(); xAwal = GetLeft(); xAkhir = GetRight(); //inisialisasi matrix jmlRegionX = (int)Math.Round((decimal)lGambar / sGambar, 0); jmlRegionY = (int)Math.Round((decimal)tGambar / sGambar, 0); matrixPutih = new int[jmlRegionX, jmlRegionY]; matrixWarna = new int[jmlRegionX, jmlRegionY]; //cek tiap pixel di gambar //jika berwarna masukkan ke warna, jika putih masukkan ke putih lebar = xAkhir - xAwal + 1; tinggi = yAkhir - yAwal + 1; for (posY = yAwal; posY <= yAkhir; posY++) { regY = (((float)posY - (float)yAwal) * (float)jmlRegionY) / (float)tinggi; //-1 untuk pixel paling terakhir if (regY == (float)jmlRegionY) regY = regY - 1; //pembulatan ke bawah regY = (float)Decimal.Truncate((decimal)regY); for (posX = xAwal; posX <= xAkhir; posX++) { regX = (((float)posX - (float)xAwal) * (float)jmlRegionX) / (float)lebar; //-1 untuk pixel terakhir if (regX == (float)jmlRegionX) regX = regX - 1; //pembulatan ke bawah regX = (float)Decimal.Truncate((decimal)regX);
//cek jika pixel putih maka masukin ke matrixPutih //jika berwarna masukkin ke matrix berwarna if (patternGambar.GetPixel(posX, posY).ToArgb() != Color.White.ToArgb())
L.42
{ matrixWarna[(int)regX, (int)regY] = matrixWarna[(int)regX, (int)regY] + 1; } else { matrixPutih[(int)regX, (int)regY] = matrixPutih[(int)regX, (int)regY] + 1; } } } TransformMatrixToPattern(); } private void TransformMatrixToPattern() { /// <summary> /// Merubah matrix yang telah dihasilkan menjadi list 'isi' pattern /// int a, b; //convert ke isi for (a = 0; a < matrixPutih.GetLength(0); a++) { for (b = 0; b < matrixPutih.GetLength(1); b++) { //jika pixel warna lebih besar dari 50% maka dimasukkan ke list 'isi' if ((float)matrixWarna[a, b] / (float)(matrixWarna[a, b] + matrixPutih[a, b]) > 0.5) { patternProses.TambahIsi(a + 1, b + 1); } } } //transfer nilai tinggi, lebar, skala patternProses.tinggi = tGambar; patternProses.lebar = lGambar; patternProses.skala = sGambar; patternProses.GenerateSamping(); } private int GetTop() { /// <summary>
L.43
/// Mencari batas atas gambar /// int a, b; for (a = 0; a < patternGambar.Height; a++) { for (b = 0; b < patternGambar.Width; b++) { if (patternGambar.GetPixel(b, a).ToArgb() != Color.White.ToArgb()) { return a; } } } return a; } private int GetBottom() { /// <summary> /// Mencari batas bawah gambar /// int a, b; for (a = patternGambar.Height - 1; a >= yAwal; a--) { for (b = 0; b < patternGambar.Width; b++) { if (patternGambar.GetPixel(b, a).ToArgb() != Color.White.ToArgb()) { return a; } } } return a; } private int GetLeft() { /// <summary> /// Mencari batas kiri gambar ///
L.44
int a, b; for (a = 0; a < patternGambar.Width; a++) { // for(b=xAwal; b<=yAkhir; b++) for (b = yAwal; b <= yAkhir; b++) { if (patternGambar.GetPixel(a, b).ToArgb() != Color.White.ToArgb()) { return a; } } } return a; } private int GetRight() { /// <summary> /// Mencari batas kanan gambar /// int a, b; for (a = patternGambar.Width - 1; a >= xAwal; a--) { for (b = yAwal; b <= yAkhir; b++) { if (patternGambar.GetPixel(a, b).ToArgb() != Color.White.ToArgb()) { return a; } } } return a; } public Bitmap patternGambar; public Pattern patternProses = new Pattern(); private int yAwal, yAkhir, xAwal, xAkhir; public int tGambar, lGambar; public int sGambar; public int[,] matrixWarna, matrixPutih; } }
L.45
1.13 Tentang.html
Tentang Penulis <style> h3 { padding-left: 10px; } .title { padding-left: 15px; } .content { padding-left: 30px; }
PERANCANGAN PROGRAM APLIKASI OPTIMASI PENGGAMBARAN POLA MOLDING PADA MESIN PENCETAKAN PLASTIK DENGAN METODE TABU SEARCH
Dibuat oleh :
Eka Surya Widjaja
1100000355
Dibimbing oleh :
Bapak Wikaria Gazali, S.Si, M.T
Bapak Haryono Soeparno, Ir., M.Sc., Dr.