Exemple #1
0
 public Scatter(LineSegment[] segs, SCATTER_SEG_DIRECTION direction=SCATTER_SEG_DIRECTION.CLOCKWISE, double dc=2, string name="")
 {
     if (!IsSegmentsLegal(segs))
         throw new Exception("线段集合不符合要求,请保证:\n" +
                             "1. 至少有3条线段\n" +
                             "2. 集合内的线段按序首尾相连\n" +
                             "3. 每条线段都不与除相临线段外的任何线段相交\n");
     this.border_segments = segs;
     this.seg_direction = direction;
     this.dielectric_constant = dc;
     int top = int.MaxValue, bottom = int.MinValue, left = int.MaxValue, right = int.MinValue;
     foreach(LineSegment seg in segs)
     {
         if (seg.Top < top)
             top = seg.Top;
         if (seg.Bottom > bottom)
             bottom = seg.Bottom;
         if (seg.Left < left)
             left = seg.Left;
         if (seg.Right > right)
             right = seg.Right;
     }
     this.border_rect.X = left;
     this.border_rect.Y = top;
     this.border_rect.Width = right - left;
     this.border_rect.Height = bottom - top;
     this.name = name == "" ? "Scatter" + id.ToString() : name;
     id++;
 }
        ///// <summary>
        ///// 自由空间路径损耗
        ///// </summary>
        ///// <param name="Pi"></param>
        ///// <param name="d"></param>
        ///// <param name="freq"></param>
        ///// <returns></returns>
        //public static double FreeSpacePathLoss(double Pi, double d, double freq)
        //{
        //    double dbi = 20 * Math.Log10(freq / 1e6) + 20 * Math.Log10(d / 1e3);
        //    double ratio = Math.Pow(10, (dbi / 10));
        //    return Pi / ratio;
        //}

        /// <summary>
        /// 计算镜面反射角
        /// </summary>
        /// <param name="ray">入射波束线段</param>
        /// <param name="barrier">产生碰撞的散射体线段</param>
        /// <param name="dir">散射体的向量旋转方向</param>
        /// /// <returns>出射角</returns>
        public static double SpecularReflection(LineSegment ray, LineSegment barrier, SCATTER_SEG_DIRECTION dir)
        {
            double result;
            double angle = ray.Angle(barrier);
            if(dir == SCATTER_SEG_DIRECTION.CLOCKWISE)
            {
                result = barrier.DirectionRadian + angle;
                result = result > Math.PI * 2 ? result - Math.PI * 2 : result;
            }
            else
            {
                result = barrier.DirectionRadian - angle;
                result = result < 0 ? result + Math.PI * 2 : result;
            }
            return result;
        }
Exemple #3
0
 public Scatter(Point[] vertices, SCATTER_SEG_DIRECTION direction=SCATTER_SEG_DIRECTION.CLOCKWISE, double dc=2, string name="")
 {
     Exception ex = new Exception("顶点集合不符合要求,请保证:\n" +
                                  "1. 至少有3个顶点\n" +
                                  "2. 顶点按序连成的每条线段都不与除相临线段外的任何线段相交\n");
     if (vertices.Length < 3)
         throw ex;
     List<LineSegment> segs = new List<LineSegment>();
     for(int i = 1; i < vertices.Length; i++)
     {
         segs.Add(new LineSegment(vertices[i - 1], vertices[i]));
     }
     segs.Add(new LineSegment(vertices[vertices.Length - 1], vertices[0]));
     LineSegment[] sgs = segs.ToArray();
     if (!IsSegmentsLegal(sgs))
         throw ex;
     this.border_segments = sgs;
     this.seg_direction = direction;
     this.dielectric_constant = dc;
     int top = int.MaxValue, bottom = int.MinValue, left = int.MaxValue, right = int.MinValue;
     foreach (LineSegment seg in segs)
     {
         if (seg.Top < top)
             top = seg.Top;
         if (seg.Bottom > bottom)
             bottom = seg.Bottom;
         if (seg.Left < left)
             left = seg.Left;
         if (seg.Right > right)
             right = seg.Right;
     }
     this.border_rect.X = left;
     this.border_rect.Y = top;
     this.border_rect.Width = right - left;
     this.border_rect.Height = bottom - top;
     this.name = name == "" ? "Scatter" + id.ToString() : name;
     id++;
 }
Exemple #4
0
 /// <summary>
 /// 获取反射点坐标及碰撞线段和碰撞散射体的旋转方向
 /// </summary>
 /// <param name="seg"></param>
 /// <param name="collision_seg"></param>
 /// <param name="dir"></param>
 /// <returns></returns>
 public Point? GetClosestReflectionPoint(LineSegment seg, out LineSegment collision_seg, out SCATTER_SEG_DIRECTION dir, out double dc)
 {
     Dictionary<Point?, object[]> pt_seg_dir_dict = new Dictionary<Point?, object[]>();
     foreach (Scatter scatter in this.Scatters)
     {
         Point? tmp_pt = null;
         LineSegment tmp_seg = null;
         SCATTER_SEG_DIRECTION tmp_dir = scatter.SegDirection;
         double tmp_dc = scatter.DielectricConstant;
         tmp_pt = scatter.GetClosestReflectionPoint(seg, out tmp_seg);
         if (tmp_pt != null)
             pt_seg_dir_dict.Add(tmp_pt, new object[] { tmp_seg, tmp_dir, tmp_dc });
     }
     if(pt_seg_dir_dict.Count == 0)  //没有交点
     {
         collision_seg = null;
         dir = SCATTER_SEG_DIRECTION.CLOCKWISE;
         dc = 0;
         return null;
     }
     KeyValuePair<Point?, object[]> tmp_kvp = pt_seg_dir_dict.First();
     double min_d2 = double.PositiveInfinity;
     foreach (KeyValuePair<Point?, object[]> kvp in pt_seg_dir_dict)
     {
         double dist2 = Math.Pow(kvp.Key.Value.X - seg.TailPosition.X, 2) + Math.Pow(kvp.Key.Value.Y - seg.TailPosition.Y, 2);
         if (dist2 > 0 && dist2 < min_d2)
         {
             min_d2 = dist2;
             tmp_kvp = kvp;
         }
     }
     collision_seg = tmp_kvp.Value[0] as LineSegment;
     dir = (SCATTER_SEG_DIRECTION)tmp_kvp.Value[1];
     dc = (double)tmp_kvp.Value[2];
     return tmp_kvp.Key;
 }