/// <summary> /// Функция С.Братта для создания каталога триадных признаков на основе вычисленной звездной /// величины отсечки. Создает список углов точечного произведения между звездой и следующими /// двумя самыми близкими звездами.Также находит интерьер точечного угла между этими тремя звездами. /// </summary> public static List <Triangles> Triad_Feature_Extract(double Mg, double FOV, List <Star> catalog) { List <Triangles> feat = new List <Triangles>(); //feat.Add(new Triangles(-1, -1, -1, -1, -1, -1)); // заглушка, чтоб начиналос с 1го индекса Vector3 A; Vector3 B; Vector3 C; Vector3 Vec1, Vec2; int Hip1, Hip2, Hip3; int Hiparc2, Hiparc3; double theta, theta1, theta2; Vector3 NewXYZ; double v1, v2; double phi; double ang1, ang2; int tempindex = 0; for (int j = 0; j < catalog.Count; j++) { A = catalog[j].GetXYZ(); // Желаемый вектор для сравнения B = C = Vector3.Zero; Hip1 = catalog[j].Id; Hip2 = Hip3 = -1; theta1 = theta2 = 360; for (int i = 0; i < catalog.Count; i++) { //Получить 2й вектор NewXYZ = catalog[i].GetXYZ(); if (!NewXYZ.Equals(A)) { // Найти угол между нужным вектором и вторым вектором theta = Math.Acos(Vector3.Dot(A, NewXYZ)); //Сравнить и обновить углы if (theta1 < theta && theta < theta2) { theta2 = theta; Hip3 = catalog[i].Id; C = NewXYZ; } else if (theta < theta1) { theta2 = theta1; theta1 = theta; Hip3 = Hip2; Hip2 = catalog[i].Id; C = B; B = NewXYZ; } } } //Внутренние векторы и величины Vec1 = B - A; Vec2 = C - A; v1 = Vec1.Length(); v2 = Vec2.Length(); phi = Math.Acos(Vector3.Dot(Vec1, Vec2) / (v1 * v2)); if (theta1 > theta2) { ang1 = theta2; ang2 = theta1; Hiparc2 = Hip3; Hiparc3 = Hip2; } else { ang1 = theta1; ang2 = theta2; Hiparc2 = Hip2; Hiparc3 = Hip3; } tempindex++; feat.Add(new Triangles(Hip1, Hiparc2, Hiparc3, ang1, ang2, phi)); } return(feat); }
/// <summary> /// 3-звездочный алгоритм идентификации звезды триады-Лейбе Получает точечные произведения и /// внутренние углы двух ближайших звезд к конкретной звезды.Это ограничено только двумя /// ближайшими звездами рядом с рассматриваемой звездой. /// </summary> public static List <StarID> GetThreeStar_ID(List <Star> catalog, List <Triangles> featurelist, List <SpotList> spotlist, double ecat) { List <Pattern> pattern = new List <Pattern>(); //pattern.Add(new Pattern(-1, -1, -1, -1, -1, -1)); // заплатка, чтоб всё было с единицы Vector3 A; Vector3 B; Vector3 C; Vector3 Vec1, Vec2; int spot1, spot2, spot3; int Spot2, Spot3; double theta, theta1, theta2; Vector3 New; double v1, v2; double phi; double ang1, ang2; for (int j = 0; j < spotlist.Count; j++) { A = spotlist[j].XYZ; B = C = Vector3.Zero; spot1 = spotlist[j].Spot; spot2 = spot3 = 0; theta1 = theta2 = 360; for (int i = 0; i < spotlist.Count; i++) { New = spotlist[i].XYZ; if (!New.Equals(A)) { theta = Math.Acos(Vector3.Dot(A, New) / (Vector3Norm(A) * Vector3Norm(New))); if (theta < theta2 && theta > theta1) { theta2 = theta; spot3 = spotlist[i].Spot; C = New; } else if (theta < theta1) { theta2 = theta1; theta1 = theta; spot3 = spot2; spot2 = spotlist[i].Spot; C = B; B = New; } } } //ПОЛУЧИТЬ внутренний угол (фи) Vec1 = B - A; Vec2 = C - A; v1 = Vec1.Length(); v2 = Vec2.Length(); phi = Math.Acos(Vector3.Dot(Vec1, Vec2) / (v1 * v2)); if (theta1 > theta2) { ang1 = theta2; ang2 = theta1; Spot2 = spot3; Spot3 = spot2; } else { ang1 = theta1; ang2 = theta2; Spot2 = spot2; Spot3 = spot3; } pattern.Add(new Pattern(spot1, Spot2, Spot3, ang1, ang2, phi)); } // Поиск Список возможностей ПОЛУЧИТЬ совпадения List <Pattern> match = new List <Pattern>(); //match.Add(new Pattern(-1, -1, -1, -1, -1, -1)); List <double> fAng1 = new List <double>(); List <double> fAng2 = new List <double>(); List <double> fAng3 = new List <double>(); for (int i = 0; i < featurelist.Count; i++) { fAng1.Add(featurelist[i].Theta1); fAng2.Add(featurelist[i].Theta2); fAng3.Add(featurelist[i].Phi); } for (int i = 0; i < pattern.Count; i++) { double high1 = pattern[i].Theta1 + ecat; double low1 = pattern[i].Theta1 - ecat; double high2 = pattern[i].Theta2 + ecat; double low2 = pattern[i].Theta2 - ecat; double high3 = pattern[i].Phi + ecat; double low3 = pattern[i].Phi - ecat; #region аналог булевских операций из матлаба с массивами // по идее массивы должны быть булевские, но с int потом легче работать List <int> ind1 = new List <int>(); List <int> ind2 = new List <int>(); List <int> ind3 = new List <int>(); List <int> ind4 = new List <int>(); List <int> ind5 = new List <int>(); List <int> ind6 = new List <int>(); for (int ll = 0; ll < fAng1.Count; ll++) { ind1.Add(fAng1[ll] <= high1 ? 1 : 0); ind2.Add(fAng1[ll] >= low1 ? 1 : 0); ind3.Add(fAng2[ll] <= high2 ? 1 : 0); ind4.Add(fAng2[ll] >= low2 ? 1 : 0); ind5.Add(fAng3[ll] <= high3 ? 1 : 0); ind6.Add(fAng3[ll] >= low3 ? 1 : 0); } List <int> index = new List <int>(); //index.Add(0); for (int ll = 0; ll < ind1.Count; ll++) { index.Add((ind1[ll] + ind2[ll] + ind3[ll] + ind4[ll] + ind5[ll] + ind5[ll]) == 6 ? 1 : 0); } #endregion аналог булевских операций из матлаба с массивами if (index.Sum() == 0) { match.Add(new Pattern(0, 0, 0, 0, 0, 0)); } else { int IndexTrue = FoundListBoolTrue(index); match.Add(new Pattern(featurelist[IndexTrue].HipID1, featurelist[IndexTrue].HipID2, featurelist[IndexTrue].HipID3, featurelist[IndexTrue].Theta1, featurelist[IndexTrue].Theta2, featurelist[IndexTrue].Phi)); } } //Спаривание мест для звезд (мини-голосование) List <StarID> starID = new List <StarID>(); //starID.Add(new StarID(-1, -1, -1, -1, -1, -1)); List <int> ps1 = new List <int>(); List <int> ps2 = new List <int>(); List <int> ps3 = new List <int>(); List <int> ms1 = new List <int>(); List <int> ms2 = new List <int>(); List <int> ms3 = new List <int>(); for (int i = 0; i < pattern.Count; i++) { ps1.Add(pattern[i].Spot1); ps2.Add(pattern[i].Spot2); ps3.Add(pattern[i].Spot3); } for (int i = 0; i < match.Count; i++) { ms1.Add(match[i].Spot1); ms2.Add(match[i].Spot2); ms3.Add(match[i].Spot3); } for (int i = 0; i < spotlist.Count; i++) { List <int> hip1 = new List <int>(); List <int> hip2 = new List <int>(); List <int> hip3 = new List <int>(); List <int> hip = new List <int>(); for (int j = 0; j < ms1.Count; j++) { if (ps1[j] == i) { hip1.Add(ms1[j]); } if (ps2[j] == i) { hip2.Add(ms2[j]); } if (ps3[j] == i) { hip3.Add(ms3[j]); } } hip.AddRange(hip1); hip.AddRange(hip2); hip.AddRange(hip3); hip.RemoveAll(p => p == 0); // удаление всего, что равно 0 List <int> uhip = hip.AsQueryable().Distinct().ToList(); // удаляем все повторения, делая лист с уникальными значеними List <int> votes = new List <int>(); int vote; int index; if (uhip.Count != 0) { for (int j = 0; j < uhip.Count; j++) { votes.Add(hip.Where(x => x == uhip[j]).Count()); } vote = votes.Max(); index = votes.IndexOf(vote); starID.Add(new StarID(votes.Max(), i, votes.IndexOf(vote), spotlist[i].XYZ)); } else { vote = index = 0; starID.Add(new StarID(0, i, 0, spotlist[i].XYZ)); } //starID.Add(new StarID(vote, i, uhip[index], spotlist[i].XYZ)); } return(starID); }
public override int GetHashCode() { int hash = 1; if (Vno.Length != 0) { hash ^= Vno.GetHashCode(); } if (VColor != 0) { hash ^= VColor.GetHashCode(); } if (FromChannel.Length != 0) { hash ^= FromChannel.GetHashCode(); } if (Encrypt != 0) { hash ^= Encrypt.GetHashCode(); } if (GpsTime != 0L) { hash ^= GpsTime.GetHashCode(); } if (Lon != 0L) { hash ^= Lon.GetHashCode(); } if (Lat != 0L) { hash ^= Lat.GetHashCode(); } if (Vec1 != 0) { hash ^= Vec1.GetHashCode(); } if (Vec2 != 0) { hash ^= Vec2.GetHashCode(); } if (Vec3 != 0) { hash ^= Vec3.GetHashCode(); } if (Direction != 0) { hash ^= Direction.GetHashCode(); } if (Altitude != 0) { hash ^= Altitude.GetHashCode(); } if (State != 0) { hash ^= State.GetHashCode(); } if (Alarm != 0) { hash ^= Alarm.GetHashCode(); } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } return(hash); }