using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Txgy.EWS.Client.FocalMechanism.Model; using Txgy.Microseismic.BaseLib.Models; using FMStation = Txgy.EWS.Client.FocalMechanism.Model.FMStation; namespace Txgy.EWS.Client.FocalMechanism.Core { /// /// 倾滑 /// public class CrossLineFactory : Factory { public CrossLine[] cross { get; set; } public CrossLineFactory(Model.FmGrid g) : base(g) { cross = new CrossLine[90]; } /// /// 判断是否为倾滑 /// /// /// public ComputationResult generateResult(FMMap map) { ComputationResult r = null; CrossLine cl = computeCross(map); if (cl != null) { r = new ComputationResult(); r.graph = cl; r.Direction = cl.Lines[0].angle; r.FocalType = FocalMechanismType.dipSlip; map.T = FocalMechanismType.dipSlip; } return r; } private CrossLine computeCross(FMMap map) { for (int i = 0; i < 90; i++) { List l = new List(); for (int j = 0; j < map.posStation.Count; j++) { int fj = grid.StationList.ToList().FindIndex(fi => fi.Name == map.posStation[j]); if (fj == -1) continue; l.Add(0 - this.grid.distance[i + 90, fj]); } for (int j = 0; j < map.negStation.Count; j++) { int fj = grid.StationList.ToList().FindIndex(fi => fi.Name == map.negStation[j]); if (fj == -1) continue; l.Add(0 - this.grid.distance[i + 90, fj]); } l.Sort(); CrossLine c = null; for (int j = 0; j < l.Count - 1; j++) { c = getCross((l[j] + l[j + 1]) / 2, i, map); if (c != null) { c.horDiff = l[j+1] - l[j]; //Select the crossline with the biggest min diff if (cross[i]==null || Math.Min(c.horDiff, c.verDiff) > Math.Min(cross[i].horDiff, cross[i].verDiff)) { cross[i] = c; } } } } int firstAngle = -1, maxAngle = -1, tempA = 0; for (int i = 1; i < 180; i++) { if (cross[i % 90] != null && cross[(i - 1) % 90] == null) { firstAngle = i; } if (cross[i % 90] == null && cross[(i - 1) % 90] != null) { if (firstAngle != -1) { int diff = i - 1 - firstAngle; if (diff > maxAngle) { tempA = firstAngle + diff / 2; maxAngle = diff; } firstAngle = -1; } } } if (tempA >= 90) tempA -= 90; if (cross[tempA] == null) return null; return cross[tempA]; } private CrossLine getCross(double x, int angle, FMMap map) { if(angle>=90) return null; double posleftMax = int.MinValue; double posrightMax = int.MinValue; double posleftMin = int.MaxValue; double posrightMin = int.MaxValue; double negleftMax = int.MinValue; double negrightMax = int.MinValue; double negleftMin = int.MaxValue; double negrightMin = int.MaxValue; for (int i = 0; i < map.posStation.Count; i++) { int fj = grid.StationList.ToList().FindIndex(fi => fi.Name == map.posStation[i]); if (fj == -1) continue; double xpos = 0 - this.grid.distance[angle + 90, fj]; double ypos = this.grid.distance[angle, fj]; if (xpos <= x) { posleftMax = Math.Max(posleftMax, ypos); posleftMin = Math.Min(posleftMin, ypos); } else { posrightMax = Math.Max(posrightMax, ypos); posrightMin = Math.Min(posrightMin, ypos); } } for (int i = 0; i < map.negStation.Count; i++) { int fj = grid.StationList.ToList().FindIndex(fi => fi.Name == map.negStation[i]); if (fj == -1) continue; double xpos = 0 - this.grid.distance[angle + 90, fj]; double ypos = this.grid.distance[angle, fj]; if (xpos <= x) { negleftMax = Math.Max(negleftMax, ypos); negleftMin = Math.Min(negleftMin, ypos); } else { negrightMax = Math.Max(negrightMax, ypos); negrightMin = Math.Min(negrightMin, ypos); } } //one of the area is empty. It can be discript as polygon if (posleftMax < posleftMin || negleftMax < negleftMin || posrightMax < posrightMin || negrightMax < negrightMin) return null; if (posleftMax <= posrightMin && posleftMax <= negleftMin && negrightMax <= posrightMin && negrightMax <= negleftMin) { double up = Math.Min(posrightMin, negleftMin); double down = Math.Max(posleftMax, negrightMax); var c = new CrossLine(x, (up + down) / 2, angle); c.verDiff = up - down; return c; } if (negleftMax <= negrightMin && negleftMax <= posleftMin && posrightMax <= negrightMin && posrightMax <= posleftMin) { double up = Math.Min(negrightMin, posleftMin); double down = Math.Max(negleftMax, posrightMax); var c = new CrossLine(x, (up + down) / 2, angle); c.verDiff = up - down; return c; } return null; } } }