/// <summary> /// ワールド座標、回転を使ってレイヤーマップを生成 /// </summary> /// <param name="g"></param> /// <param name="layer"></param> /// <param name="drawGuideLine"></param> /// <param name="fastDraw"></param> /// <param name="offsetX"></param> /// <param name="offsetY"></param> /// <param name="bUseView">View座標で描画(BMP出力時などはfalse)</param> private void DrawLayerToWorld(Graphics g, LayerData layer, bool drawGuideLine, bool fastDraw) { int ctrX = layer.MapBmp.Width / 2; int ctrY = layer.MapBmp.Height / 2; g.InterpolationMode = InterpolationMode.HighQualityBilinear; g.ResetTransform(); //g.ScaleTransform((float)DrawMapScale, (float)DrawMapScale); g.TranslateTransform(-ctrX, -ctrY, MatrixOrder.Append); g.RotateTransform((float)layer.wAng, MatrixOrder.Append); g.TranslateTransform(ctrX + (int)layer.wX, ctrY + (int)layer.wY, MatrixOrder.Append); // View g.ScaleTransform(ViewScale, ViewScale, MatrixOrder.Append); g.TranslateTransform(ViewTransX, ViewTransY, MatrixOrder.Append); //g.DrawImageUnscaled(layer.MapBmp, 0, 0); if (fastDraw) { // 高速描画用トライアングル g.DrawPolygon(Pens.Red, layer.psLayerTriangle); } else { // 通常描画 g.DrawImage(layer.MapBmp, 0, 0); } if (drawGuideLine) { // 枠線描画 Rectangle rect = new Rectangle(0, 0, layer.MapBmp.Width - 1, layer.MapBmp.Height - 1); Pen colPen = Pens.Silver; if (layer.drawColor == colEditLayerPixel) { colPen = new Pen(colEditLayerPixel); } g.DrawRectangle(colPen, rect); } }
/// <summary> /// 指定のインデックス以外のレイヤーを1枚のワールドマップに描画 /// </summary> /// <param name="noDrawLayer">描画しないレイヤー nullならすべて描画</param> /// <returns></returns> private void UpdateLayerMap(LayerData noDrawLayer) { //Bitmap newWorldMap = new Bitmap(WorldMapWidth, WorldMapHeight); if (null == MapLyaer) return; Graphics g = Graphics.FromImage(LayerMap); g.FillRectangle(Brushes.Black, 0, 0, LayerMap.Width, LayerMap.Height); g.InterpolationMode = InterpolationMode.NearestNeighbor; foreach (var layer in MapLyaer) { if (layer == noDrawLayer) break; if (layer.useFlg) { DrawLayerToWorld(g, layer, false, false); } } g.Dispose(); LayerMap.MakeTransparent(Color.White); //return LayerMap; }
/// <summary> /// 全レイヤー生成 /// </summary> private bool AllNewLayer() { if (null == UrgLogReader) { MessageBox.Show("LRFデータがロードされていません", "Error"); return false; } if (skipLrfIDX <= 0 || (int)(maxLRFIdx / skipLrfIDX) <= 0) { MessageBox.Show("SkipFrameが不正な値です。1以上、全フレーム以下にしてください。", "Error"); return false; } progressBar_LoadLayer.Value = 0; progressBar_LoadLayer.Maximum = (int)(maxLRFIdx / skipLrfIDX); Application.DoEvents(); { parentForm.MapLyaer = new List<LayerData>(); UrgLogReader.SetSkipNum(skipLrfIDX); //LayerData lastLayer = null; double oldAvgLrfDist = 0.0; int contCnt = 0; double[] readLRFdata = UrgLogReader.getScanData(0); while (null != readLRFdata && readLRFdata.Length > 0) { // 静止状態をチェック double avgLrfDist = CheckLRFAvg(readLRFdata); // 前回と同じか? // 10%以内の誤差 if ( Math.Abs(oldAvgLrfDist - avgLrfDist) < avgLrfDist * 0.10) { contCnt++; } else { contCnt = 0; oldAvgLrfDist = avgLrfDist; } //if (contCnt < 3) { // レイヤー作成 LayerData newLayer = new LayerData(readLRFdata); newLayer.SetLocalPosAng(0.0, 0.0, 0.0, -defDistanceLayer); newLayer.MakeMapBmp(MapEditForm.LRF_Range, MapEditForm.LRF_ScaleOfPixel, LRF_PixelSize, parentForm.colLayerPixel, parentForm.colLayerBase); /* // できた画像がほぼ同じなら、カットして、データ削減 if (cb_StopLayerCut.Checked && null != lastLayer) { // 90%以下なら静止中と判断 if (LayerMatching(newLayer, lastLayer) < 90) { parentForm.MapLyaer.Add(newLayer); lastLayer = newLayer; } } else * */ { if (contCnt < 3) { newLayer.useFlg = true; } parentForm.MapLyaer.Add(newLayer); //lastLayer = newLayer; } } // プログレスバー進行 if (progressBar_LoadLayer.Value < progressBar_LoadLayer.Maximum) { progressBar_LoadLayer.Value++; } Application.DoEvents(); // 次のデータ読み込み readLRFdata = UrgLogReader.getScanData(); } // センタリング if (parentForm.MapLyaer.Count > 0) { LayerData firstLayer = parentForm.MapLyaer[0]; firstLayer.SetLocalPosAng(-firstLayer.MapBmp.Width / 2, -firstLayer.MapBmp.Height / 2, 0.0, 0.0); parentForm.UpdateLayerData(); } } progressBar_LoadLayer.Value = 0; return true; }
/// <summary> /// LRF ピクチャボックス更新 /// </summary> /// <param name="lrfIdx"></param> private void UpdateLRFPicBox(long lrfIdx) { if (null != UrgLogReader) { if (UrgLogReader.getNextIndex() == lrfIdx) { LRFlayer = new LayerData(UrgLogReader.getScanData()); } else { // インデックスがとんだ場合 LRFlayer = new LayerData(UrgLogReader.getScanData(lrfIdx)); } LRFlayer.MakeMapBmp( MapEditForm.LRF_Range, MapEditForm.LRF_ScaleOfPixel, LRF_PixelSize, parentForm.colLayerPixel, parentForm.colLayerBase); pb_LRFLog.Image = LRFlayer.MapBmp; pb_LRFLog.Invalidate(); } }
/// <summary> /// レイヤーマップを比べる /// </summary> /// <param name="aLayer"></param> /// <param name="bLayer"></param> /// <returns>合致度(%)を返す</returns> private int LayerMatching( LayerData aLayer,LayerData bLayer ) { int matchCnt = 0; int matchNum = 0; byte baseColR = parentForm.GetMapColorBase(0); byte baseColG = parentForm.GetMapColorBase(1); byte baseColB = parentForm.GetMapColorBase(2); for(int x=0; x<aLayer.MapBmp.Width; x++ ) { for(int y=0; y<aLayer.MapBmp.Height; y++ ) { Color pixCol = aLayer.MapBmp.GetPixel(x, y); if (pixCol.R != baseColR || pixCol.G != baseColG || pixCol.B != baseColB) { matchNum++; if (pixCol == bLayer.MapBmp.GetPixel(x, y)) { matchCnt++; } } } } if (matchNum == 0) return 0; // 合致度を確認 return (matchCnt * 100 / matchNum); }
/// <summary> /// エディットレイヤー選択 /// </summary> /// <param name="selIdx"></param> private void SelectEditLayer(int selIdx) { // 前のエディットレイヤーを元のカラーに戻す if (null != EditLayer) { EditLayer.UpdateMapBmp(LRF_PixelSize, colLayerPixel, colLayerBase); } if (null != MapLyaer) { EditLayer = MapLyaer[selIdx]; EditLayer.UpdateMapBmp(LRF_PixelSize, colEditLayerPixel, colLayerBase); num_PositionX.Value = (int)EditLayer.lcX; num_PositionY.Value = (int)EditLayer.lcY; num_Angle.Value = (int)EditLayer.lcAng; cb_UseLayer.Checked = EditLayer.useFlg; UpdateEditMap(); UpdateAllLayerFLG = true; UpdateTRG = true; } }
/// <summary> /// バイナリデータ ロード /// </summary> /// <param name="strm"></param> private void Read(BinaryReader strm) { strm.ReadInt32(); // FileVersion strm.ReadInt32(); // セクション数 LRF_LogFileName = strm.ReadString(); // マップレイヤー セクション { int numLayer = strm.ReadInt32(); WaitProressBar.Value = 0; WaitProressBar.Maximum = numLayer; WaitProressBar.Step = 1; MapLyaer = new List<LayerData>(); for (int i = 0; i < numLayer; i++) { LayerData layer = new LayerData(); layer.Read(strm); layer.MakeMapBmp(LRF_Range, LRF_ScaleOfPixel, LRF_PixelSize, colLayerPixel, colLayerBase); MapLyaer.Add(layer); WaitProressBar.PerformStep(); } } // チェックポイント セクション { int numCp = strm.ReadInt32(); CheckPoints = new List<CheckPointData>(); for (int i = 0; i < numCp; i++) { CheckPointData cp = new CheckPointData(); cp.Read(strm); } UpdateCheckPointList(); } WaitProressBar.Value = 0; }