/// <summary> /// 添加接收机 /// </summary> /// <param name="rec"></param> public void AddReceiver(Receiver rec) { try { this.viz_rps.Map.AddReceiver(rec); ListViewItem lvi = new ListViewItem(rec.Name); lvi.SubItems.Add(rec.Location.ToString()); lvi.Name = rec.Name; this.lvReceivers.Items.Add(lvi); this.RePaint(); } catch (Exception ex) { MessageBox.Show("添加接收机失败:\n" + ex.Message); } }
public ReceiverEnumerator(Receiver[] receiver) { this.receivers = receiver.Clone() as Receiver[]; }
/// <summary> /// 添加接收机 /// </summary> /// <param name="transmitter"></param> public void AddReceiver(Receiver receiver) { if (receiver.Location.X < 0 || receiver.Location.X > this.Size.Width - 1 || receiver.Location.Y < 0 || receiver.Location.Y > this.Size.Height - 1) throw new Exception("添加接收机失败:坐标超出地图范围!"); foreach (Transmitter tr in this.transmitters.Values) if (tr.Location == receiver.Location) throw new Exception("添加接收机失败:坐标与现有发射机重合!"); foreach (Receiver rec in this.receivers.Values) { if (rec.Location == receiver.Location) throw new Exception("添加接收机失败:坐标与现有接收机重合!"); if (rec.Name == receiver.Name) throw new Exception("添加接收机失败:名称与现有接收机相同!"); } foreach (Scatter scatter in this.scatters.Values) if (scatter.IsPointInside(receiver.Location)) throw new Exception("添加接收机失败:坐标在现有散射体内部!"); this.receivers[receiver.Name] = receiver; }
public ReceiverCollection(Receiver[] r) { this.recs = r; }
/// <summary> /// 根据所在地图更新波束(完成一次碰撞的结算) /// </summary> /// <param name="map">所在地图</param> /// <param name="sink">返回被接收的接收机,若没被接收则返回null</param> /// <returns>若生命周期结束(被接收 || 强度过低 || 射出地图边界)则返回true,否则返回false</returns> public bool Update(Map map, out Receiver sink) { double len2 = Math.Pow(map.Size.Width, 2) + Math.Pow(map.Size.Height, 2); double[] vector = new double[] { Math.Cos(this.CurrentDirection), Math.Sin(this.CurrentDirection) }; vector[0] *= len2; vector[1] *= len2; Point dest_pt = new Point((int)Math.Round(this.CurrentLocation.X + vector[0]), (int)Math.Round(this.CurrentLocation.Y - vector[1])); LineSegment shoot_seg = new LineSegment(this.CurrentLocation, dest_pt); if (this.path_segs.Count > 0) //至少要反射一次才能被接收机接收 { List<Receiver> tmp_rec = new List<Receiver>(); foreach (Receiver rec in map.Receivers) { if (map.IsLOS(this.CurrentLocation, rec.Location)) //若接收机与当前点为视距且在波束宽度内 if(new LineSegment(this.CurrentLocation, rec.Location).Angle(shoot_seg) < this.BeamWidth / 2) tmp_rec.Add(rec); } if(tmp_rec.Count > 0) { sink = tmp_rec[new Random().Next(tmp_rec.Count)]; //随机被一满足条件的接收机接收 LineSegment l = new LineSegment(this.CurrentLocation, sink.Location); this.path_segs.Add(l); this.current_direction = this.path_segs.Last().DirectionRadian; return true; } } Point? tmp_pt = null; LineSegment tmp_seg = null; SCATTER_SEG_DIRECTION tmp_dir = SCATTER_SEG_DIRECTION.CLOCKWISE; double tmp_dc = 0; tmp_pt = map.GetClosestReflectionPoint(shoot_seg, out tmp_seg, out tmp_dir, out tmp_dc); if(tmp_pt == null) //无碰撞,射出地图边界 { sink = null; this.path_segs.Add(shoot_seg); this.current_direction = shoot_seg.DirectionRadian; return true; } else //发生碰撞 { LineSegment l = new LineSegment(this.CurrentLocation, tmp_pt.Value); this.path_segs.Add(l); double reflect_angle = RadioPropagationModel.SpecularReflection(shoot_seg, tmp_seg, tmp_dir); if(tmp_pt == tmp_seg.HeadPosition || tmp_pt == tmp_seg.TailPosition) { reflect_angle = shoot_seg.DirectionRadian + Math.PI; if(reflect_angle > Math.PI * 2) reflect_angle -= Math.PI * 2; } this.current_direction = RadioPropagationModel.DiffuseReflection(reflect_angle); this.power = RadioPropagationModel.ReflectionLoss(this.UnfadedPower, shoot_seg, tmp_seg, tmp_dc); sink = null; return this.FadedPower(map.MeterPixelRatio) < map.RayPowerThreshold * this.InitPower; //若碰撞后强度过低则返回true结束,否则返回false,可以继续Update } }