You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
6.5 KiB
C#

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
{
/// <summary>
/// 倾滑
/// </summary>
public class CrossLineFactory : Factory
{
public CrossLine[] cross { get; set; }
public CrossLineFactory(Model.FmGrid g) : base(g)
{
cross = new CrossLine[90];
}
/// <summary>
/// 判断是否为倾滑
/// </summary>
/// <param name="map"></param>
/// <returns></returns>
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<double> l = new List<double>();
for (int j = 0; j < map.posStation.Count; j++)
{
int fj = grid.StationList.ToList<FMStation>().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<FMStation>().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<FMStation>().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<FMStation>().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;
}
}
}