Merge branch 'monitor'
This commit is contained in:
commit
f0b589073f
22
uBIMEarthTools/Commands/Monitor/MonitorCommand.cs
Normal file
22
uBIMEarthTools/Commands/Monitor/MonitorCommand.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace uBIMEarthTools.Commands.Monitor
|
||||
{
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
public class MonitorCommand : IExternalCommand
|
||||
{
|
||||
Result IExternalCommand.Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
|
||||
{
|
||||
MonitorWindow monitorWindow = new MonitorWindow();
|
||||
monitorWindow.Show();
|
||||
return Result.Succeeded;
|
||||
}
|
||||
}
|
||||
}
|
327
uBIMEarthTools/Commands/Monitor/MonitorViewModel.cs
Normal file
327
uBIMEarthTools/Commands/Monitor/MonitorViewModel.cs
Normal file
@ -0,0 +1,327 @@
|
||||
using Autodesk.Revit.DB;
|
||||
using HelixToolkit.Wpf.SharpDX;
|
||||
using SharpDX;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using uBIMEarthTools.Core;
|
||||
using uBIMEarthTools.Model;
|
||||
using uBIMEarthTools.Utils;
|
||||
|
||||
namespace uBIMEarthTools.Commands.Monitor
|
||||
{
|
||||
internal class MonitorViewModel
|
||||
{
|
||||
public IEffectsManager EffectsManager { get; set; }
|
||||
|
||||
public Camera Camera { get; set; }
|
||||
public bool EnableSwapChainRendering { get; set; }
|
||||
|
||||
public bool EnableD2DRendering { get; set; }
|
||||
public ObservableElement3DCollection Models { get; set; }
|
||||
public ICommand OpenCommand { get; set; }
|
||||
|
||||
public MonitorViewModel()
|
||||
{
|
||||
this.Models = new ObservableElement3DCollection();
|
||||
|
||||
this.EffectsManager = new DefaultEffectsManager();
|
||||
this.Camera = new PerspectiveCamera() { NearPlaneDistance = 0.1, FarPlaneDistance = 10000000 };
|
||||
this.EnableSwapChainRendering = true;
|
||||
this.EnableD2DRendering = false;
|
||||
OpenCommand = new DelegateCommand() { ExecuteCommand = OpenXlsx };
|
||||
}
|
||||
|
||||
private void OpenXlsx(object obj)
|
||||
{
|
||||
#region 数据读取
|
||||
|
||||
#region 数据文件读取路径
|
||||
string pathstring = string.Empty;
|
||||
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||||
openFileDialog.Title = "选择Excel文件…";
|
||||
openFileDialog.Filter = "Excel文件|*.xlsx";
|
||||
openFileDialog.RestoreDirectory = false;
|
||||
openFileDialog.FilterIndex = 1;
|
||||
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
||||
pathstring = openFileDialog.FileName;
|
||||
else
|
||||
return;
|
||||
#endregion
|
||||
|
||||
Stopwatch stopwatch2 = new Stopwatch();
|
||||
stopwatch2.Start();
|
||||
List<Borehole> boreholeList = ExcelHelper.GetDataFromExcel(pathstring);
|
||||
stopwatch2.Stop();
|
||||
#endregion
|
||||
|
||||
#region 数据有效性检测
|
||||
string abc = string.Empty;
|
||||
foreach (var borehole in boreholeList)
|
||||
{
|
||||
for (int i = 0; i < borehole.ValueList.Count - 2; i++)
|
||||
{
|
||||
if (borehole.ValueList[i].Point.Z < borehole.ValueList[i + 1].Point.Z)
|
||||
{
|
||||
abc += borehole.Name + ",";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(abc))
|
||||
{
|
||||
MessageBox.Show(abc);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 拟合
|
||||
boreholeList.ForEach(x => x.Interpolation(2));
|
||||
|
||||
List<int[]> tris = Common.Delaunay(boreholeList, 10000000 / 304.8);
|
||||
var topList = boreholeList.Select(x =>
|
||||
{
|
||||
var p = x.ValueList.First();
|
||||
return new Point2D() { X = p.Point.X, Y = p.Point.Y, Value = p.Point.Z };
|
||||
}).ToList();
|
||||
var topKriging = new IDW<Point2D>(topList, 2);
|
||||
|
||||
var bottomList = boreholeList.Select(x =>
|
||||
{
|
||||
var p = x.ValueList.Last();
|
||||
return new Point2D() { X = p.Point.X, Y = p.Point.Y, Value = p.Point.Z };
|
||||
}).ToList();
|
||||
var bottomKriging = new IDW<Point2D>(bottomList, 2);
|
||||
|
||||
var typeValue = new Dictionary<string, int>();
|
||||
var valueType = new Dictionary<int, string>();
|
||||
var types = boreholeList.SelectMany(x => x.ValueList.Select(p => p.Type)).Distinct().ToList();
|
||||
for (int i = 0; i < types.Count; i++)
|
||||
{
|
||||
typeValue.Add(types[i], i + 1);
|
||||
valueType.Add(i + 1, types[i]);
|
||||
}
|
||||
var boreholeKriging = new IDW<Point3D>(boreholeList.SelectMany(b => b.ValueList.Select(p => new Point3D() { X = p.Point.X, Y = p.Point.Y, Z = p.Point.Z, Value = typeValue[p.Type] })).ToList(), 2);
|
||||
|
||||
List<Borehole> boreholes1 = new List<Borehole>();
|
||||
//tris.AsParallel().ForAll(item =>
|
||||
//{
|
||||
// Func<XYZ, Borehole> func = (p =>
|
||||
// {
|
||||
// var topZ = topKriging.Interpolate(new Point2D() { X = p.X, Y = p.Y });
|
||||
// var bottomZ = bottomKriging.Interpolate(new Point2D() { X = p.X, Y = p.Y });
|
||||
// var plus = (topZ - bottomZ) / 10;
|
||||
// var geologyLayers = new List<GeologyLayer>();
|
||||
// for (int i = 0; i < 10; i++)
|
||||
// {
|
||||
// var p3d = new Point3D() { X = p.X, Y = p.Y, Z = topZ - i * plus };
|
||||
// var value = boreholeKriging.Interpolate2(p3d);
|
||||
// geologyLayers.Add(new GeologyLayer(valueType[(int)Math.Round(value)], new Autodesk.Revit.DB.XYZ(p3d.X, p3d.Y, p3d.Z)));
|
||||
// }
|
||||
// return new Borehole("", geologyLayers);
|
||||
// });
|
||||
|
||||
// var v1 = boreholeList.ElementAt(item[1]).ValueList[0].Point - boreholeList.ElementAt(item[0]).ValueList[0].Point;
|
||||
// var v2 = boreholeList.ElementAt(item[2]).ValueList[0].Point - boreholeList.ElementAt(item[0]).ValueList[0].Point;
|
||||
// var originP = boreholeList.ElementAt(item[0]).ValueList[0].Point;
|
||||
// var triangle = new List<XYZ>() { boreholeList.ElementAt(item[0]).ValueList[0].Point,
|
||||
// boreholeList.ElementAt(item[1]).ValueList[0].Point,
|
||||
// boreholeList.ElementAt(item[2]).ValueList[0].Point };
|
||||
// var seg = 10;
|
||||
// v1 = v1 / seg;
|
||||
// v2 = v2 / seg;
|
||||
// for (int i = 0; i < seg; i++)
|
||||
// {
|
||||
// for (int j = 0; j < seg; j++)
|
||||
// {
|
||||
// if (i == j && i == 0) { continue; }
|
||||
// var xyz = originP + v1 * i + v2 * j;
|
||||
// if (IsInPolygon(xyz, triangle))
|
||||
// {
|
||||
// boreholes1.Add(func(xyz));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//});
|
||||
//foreach (int[] item in tris)
|
||||
//{
|
||||
|
||||
//}
|
||||
#endregion
|
||||
boreholeList.AddRange(boreholes1);
|
||||
|
||||
#region 计算地质块
|
||||
List<int[]> triIndexList = Common.Delaunay(boreholeList, 10000000 / 304.8);
|
||||
List<GeologyBlock> geologyBlocks = new List<GeologyBlock>();
|
||||
foreach (int[] item in triIndexList)
|
||||
{
|
||||
List<Borehole> boreholes = new List<Borehole>() {
|
||||
new Borehole(boreholeList.ElementAt(item[0])),
|
||||
new Borehole(boreholeList.ElementAt(item[1])),
|
||||
new Borehole(boreholeList.ElementAt(item[2]))
|
||||
};
|
||||
|
||||
bool topToBottom = true;
|
||||
while (boreholes[0].StartIndex != boreholes[0].EndIndex
|
||||
|| boreholes[1].StartIndex != boreholes[1].EndIndex
|
||||
|| boreholes[2].StartIndex != boreholes[2].EndIndex)
|
||||
{
|
||||
if (topToBottom)
|
||||
{
|
||||
boreholes[0].CurrentType = boreholes[0].StartIndex != boreholes[0].EndIndex ? boreholes[0].ValueList[boreholes[0].StartIndex + 1].Type : "Last1";
|
||||
boreholes[1].CurrentType = boreholes[1].StartIndex != boreholes[1].EndIndex ? boreholes[1].ValueList[boreholes[1].StartIndex + 1].Type : "Last2";
|
||||
boreholes[2].CurrentType = boreholes[2].StartIndex != boreholes[2].EndIndex ? boreholes[2].ValueList[boreholes[2].StartIndex + 1].Type : "Last3";
|
||||
boreholes = boreholes.OrderByDescending(x => x.ValueList[x.StartIndex].Point.Z).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
boreholes[0].CurrentType = boreholes[0].StartIndex != boreholes[0].EndIndex ? boreholes[0].ValueList[boreholes[0].EndIndex].Type : "Last1";
|
||||
boreholes[1].CurrentType = boreholes[1].StartIndex != boreholes[1].EndIndex ? boreholes[1].ValueList[boreholes[1].EndIndex].Type : "Last2";
|
||||
boreholes[2].CurrentType = boreholes[2].StartIndex != boreholes[2].EndIndex ? boreholes[2].ValueList[boreholes[2].EndIndex].Type : "Last3";
|
||||
boreholes = boreholes.OrderBy(x => x.ValueList[x.EndIndex].Point.Z).ToList();
|
||||
}
|
||||
DataListSort(boreholes);
|
||||
GeologyCompute.CreateGeologyBlock(boreholes, geologyBlocks, topToBottom);
|
||||
topToBottom = !topToBottom;
|
||||
}
|
||||
|
||||
// break;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region 显示
|
||||
var colors = new Dictionary<string, Color4>();
|
||||
Random random = new Random();
|
||||
|
||||
foreach (var item in geologyBlocks.Select(x => x.Type).Distinct())
|
||||
{
|
||||
colors.Add(item, PhongMaterials.ToColor(random.Next(0, 255) / 255f, random.Next(0, 255) / 255f, random.Next(0, 255) / 255f));
|
||||
}
|
||||
|
||||
var origin = new SharpDX.Vector3((float)geologyBlocks.First().FLeftUp.X, (float)geologyBlocks.First().FLeftUp.Z, -(float)geologyBlocks.First().FLeftUp.Y);
|
||||
foreach (var item in geologyBlocks.GroupBy(g => g.Type))
|
||||
{
|
||||
var index = 0;
|
||||
List<SharpDX.Vector3> vector3s = new List<SharpDX.Vector3>();
|
||||
List<int> indices = new List<int>();
|
||||
foreach (var x in item)
|
||||
{
|
||||
vector3s.Add(new SharpDX.Vector3((float)x.FLeftUp.X, (float)x.FLeftUp.Z, -(float)x.FLeftUp.Y)); //0
|
||||
vector3s.Add(new SharpDX.Vector3((float)x.FLeftBottom.X, (float)x.FLeftBottom.Z, -(float)x.FLeftBottom.Y)); //1
|
||||
vector3s.Add(new SharpDX.Vector3((float)x.FRightUp.X, (float)x.FRightUp.Z, -(float)x.FRightUp.Y)); //2
|
||||
vector3s.Add(new SharpDX.Vector3((float)x.FRightBottom.X, (float)x.FRightBottom.Z, -(float)x.FRightBottom.Y)); //3
|
||||
vector3s.Add(new SharpDX.Vector3((float)x.ELeftUp.X, (float)x.ELeftUp.Z, -(float)x.ELeftUp.Y)); //4
|
||||
vector3s.Add(new SharpDX.Vector3((float)x.ELeftBottom.X, (float)x.ELeftBottom.Z, -(float)x.ELeftBottom.Y)); //5
|
||||
vector3s.Add(new SharpDX.Vector3((float)x.ERightUp.X, (float)x.ERightUp.Z, -(float)x.ERightUp.Y)); //6
|
||||
vector3s.Add(new SharpDX.Vector3((float)x.ERightBottom.X, (float)x.ERightBottom.Z, -(float)x.ERightBottom.Y)); //7
|
||||
|
||||
indices.Add(0 + index); indices.Add(2 + index); indices.Add(6 + index);
|
||||
indices.Add(0 + index); indices.Add(6 + index); indices.Add(4 + index);
|
||||
indices.Add(0 + index); indices.Add(3 + index); indices.Add(2 + index);
|
||||
indices.Add(3 + index); indices.Add(0 + index); indices.Add(1 + index);
|
||||
indices.Add(6 + index); indices.Add(2 + index); indices.Add(3 + index);
|
||||
indices.Add(6 + index); indices.Add(3 + index); indices.Add(7 + index);
|
||||
|
||||
indices.Add(0 + index); indices.Add(4 + index); indices.Add(1 + index);
|
||||
indices.Add(1 + index); indices.Add(4 + index); indices.Add(5 + index);
|
||||
indices.Add(4 + index); indices.Add(6 + index); indices.Add(7 + index);
|
||||
indices.Add(4 + index); indices.Add(7 + index); indices.Add(5 + index);
|
||||
indices.Add(5 + index); indices.Add(7 + index); indices.Add(1 + index);
|
||||
indices.Add(1 + index); indices.Add(7 + index); indices.Add(3 + index);
|
||||
|
||||
index = vector3s.Count;
|
||||
}
|
||||
|
||||
MeshGeometry3D me = new MeshGeometry3D();
|
||||
me.Positions = new Vector3Collection(vector3s.Select(p => p - origin));
|
||||
me.Indices = new IntCollection(indices);
|
||||
me.Normals = me.CalculateNormals();
|
||||
Models.Add(new MeshGeometryModel3D()
|
||||
{
|
||||
Geometry = me,
|
||||
FillMode = SharpDX.Direct3D11.FillMode.Solid,
|
||||
Material = new PhongMaterial()
|
||||
{
|
||||
AmbientColor = colors[item.Key],
|
||||
// SpecularColor = new SharpDX.Color4(0.0225f, 0.0225f, 0.0225f, 1.0f),
|
||||
//EmissiveColor = new SharpDX.Color4(0.0f, 0.0f, 0.0f, 1.0f),
|
||||
SpecularShininess = 12.8f,
|
||||
// DiffuseColor = colors[x.Type],
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
InitCamera();
|
||||
}
|
||||
|
||||
|
||||
public void InitCamera()
|
||||
{
|
||||
if (Models.Any())
|
||||
{
|
||||
var maxbox = Models.Select(x => x.Bounds).Aggregate(BoundingBox.Merge);
|
||||
var size = maxbox.Size;
|
||||
var maxLength = size.X > size.Y ? size.X > size.Z ? size.X : size.Z : size.Y > size.Z ? size.Y : size.Z;
|
||||
var radius = Vector3.Distance(maxbox.Center, new Vector3(maxbox.Center.X + (maxLength / 2), maxbox.Center.Y + (maxLength / 2), maxbox.Center.Z + (maxLength / 2)));
|
||||
var vec = (maxbox.Center + new Vector3(radius, radius, radius));
|
||||
this.Camera.Position = vec.ToPoint3D();
|
||||
this.Camera.LookDirection = (maxbox.Center - vec).ToVector3D();
|
||||
this.Camera.UpDirection = new Vector3(0, 1, 0).ToVector3D();
|
||||
//this.Camera.ZoomExtents();
|
||||
}
|
||||
}
|
||||
private static void DataListSort(List<Borehole> boreholes)
|
||||
{
|
||||
if (boreholes.First().CurrentType.Contains("Last"))
|
||||
{
|
||||
boreholes.Add(boreholes.First());
|
||||
boreholes.RemoveAt(0);
|
||||
DataListSort(boreholes);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
public static bool IsInPolygon(XYZ checkPoint, List<XYZ> polygonPoints)
|
||||
{
|
||||
bool inSide = false;
|
||||
int pointCount = polygonPoints.Count;
|
||||
XYZ p1, p2;
|
||||
for (int i = 0, j = pointCount - 1; i < pointCount; j = i, i++)//第一个点和最后一个点作为第一条线,之后是第一个点和第二个点作为第二条线,之后是第二个点与第三个点,第三个点与第四个点...
|
||||
{
|
||||
p1 = polygonPoints[i];
|
||||
p2 = polygonPoints[j];
|
||||
if (checkPoint.Y < p2.Y)
|
||||
{//p2在射线之上
|
||||
if (p1.Y <= checkPoint.Y)
|
||||
{//p1正好在射线中或者射线下方
|
||||
if ((checkPoint.Y - p1.Y) * (p2.X - p1.X) > (checkPoint.X - p1.X) * (p2.Y - p1.Y))//斜率判断,在P1和P2之间且在P1P2右侧
|
||||
{
|
||||
//射线与多边形交点为奇数时则在多边形之内,若为偶数个交点时则在多边形之外。
|
||||
//由于inside初始值为false,即交点数为零。所以当有第一个交点时,则必为奇数,则在内部,此时为inside=(!inside)
|
||||
//所以当有第二个交点时,则必为偶数,则在外部,此时为inside=(!inside)
|
||||
inSide = (!inSide);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (checkPoint.Y < p1.Y)
|
||||
{
|
||||
//p2正好在射线中或者在射线下方,p1在射线上
|
||||
if ((checkPoint.Y - p1.Y) * (p2.X - p1.X) < (checkPoint.X - p1.X) * (p2.Y - p1.Y))//斜率判断,在P1和P2之间且在P1P2右侧
|
||||
{
|
||||
inSide = (!inSide);
|
||||
}
|
||||
}
|
||||
}
|
||||
return inSide;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
44
uBIMEarthTools/Commands/Monitor/MonitorWindow.xaml
Normal file
44
uBIMEarthTools/Commands/Monitor/MonitorWindow.xaml
Normal file
@ -0,0 +1,44 @@
|
||||
<Window
|
||||
x:Class="uBIMEarthTools.Commands.Monitor.MonitorWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:hx="http://helix-toolkit.org/wpf/SharpDX"
|
||||
xmlns:local="clr-namespace:uBIMEarthTools.Commands.Monitor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Title="MonitorWindow"
|
||||
Width="800"
|
||||
Height="450"
|
||||
mc:Ignorable="d">
|
||||
<Window.DataContext>
|
||||
<local:MonitorViewModel />
|
||||
</Window.DataContext>
|
||||
<DockPanel>
|
||||
<Menu DockPanel.Dock="Top">
|
||||
<MenuItem Command="{Binding OpenCommand}" Header="Open Xlsx" />
|
||||
</Menu>
|
||||
<hx:Viewport3DX
|
||||
Name="Viewport"
|
||||
x:FieldModifier="public"
|
||||
Background="White"
|
||||
BackgroundColor="White"
|
||||
Camera="{Binding Camera}"
|
||||
EffectsManager="{Binding EffectsManager}"
|
||||
EnableD2DRendering="{Binding EnableD2DRendering}"
|
||||
EnableSwapChainRendering="{Binding EnableSwapChainRendering}"
|
||||
FXAALevel="High"
|
||||
MSAA="Eight">
|
||||
<hx:GroupModel3D Name="Light">
|
||||
<hx:AmbientLight3D Color="Azure" />
|
||||
<!--<hx:DirectionalLight3D Direction="3.150000,-8.090000,-4.960000" Color="SlateGray" />
|
||||
<hx:DirectionalLight3D Direction="8.610000,4.820000,1.640000" Color="SeaShell" />
|
||||
<hx:DirectionalLight3D Direction="-9.490000,3.090000,0.600000" Color="LightGray" />
|
||||
<hx:DirectionalLight3D Direction="-5.500000,-8.300000,-1.100000" Color="Azure" />-->
|
||||
</hx:GroupModel3D>
|
||||
<hx:GroupModel3D
|
||||
Name="Model"
|
||||
x:FieldModifier="public"
|
||||
ItemsSource="{Binding Models}" />
|
||||
</hx:Viewport3DX>
|
||||
</DockPanel>
|
||||
</Window>
|
27
uBIMEarthTools/Commands/Monitor/MonitorWindow.xaml.cs
Normal file
27
uBIMEarthTools/Commands/Monitor/MonitorWindow.xaml.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace uBIMEarthTools.Commands.Monitor
|
||||
{
|
||||
/// <summary>
|
||||
/// MonitorWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class MonitorWindow : Window
|
||||
{
|
||||
public MonitorWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
155
uBIMEarthTools/Core/Kriging.cs
Normal file
155
uBIMEarthTools/Core/Kriging.cs
Normal file
@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace uBIMEarthTools.Core
|
||||
{
|
||||
public class IDW<T> where T : Distance<T>
|
||||
{
|
||||
private List<T> dataPoints;
|
||||
private int power;
|
||||
|
||||
public IDW(List<T> dataPoints, int power)
|
||||
{
|
||||
this.dataPoints = dataPoints;
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public double Interpolate(T targetPoint)
|
||||
{
|
||||
double weightedSum = 0;
|
||||
double weightSum = 0;
|
||||
|
||||
foreach (var dataPoint in dataPoints)
|
||||
{
|
||||
double distance = targetPoint.DistanceTo(dataPoint);
|
||||
double weight = 1 / Math.Pow(distance, power);
|
||||
|
||||
weightedSum += weight * dataPoint.Value;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
return weightedSum / weightSum;
|
||||
}
|
||||
|
||||
public double Interpolate2(T targetPoint)
|
||||
{
|
||||
Dictionary<double,double> map = new Dictionary<double,double>();
|
||||
foreach (var dataPoint in dataPoints)
|
||||
{
|
||||
double distance = targetPoint.DistanceTo(dataPoint);
|
||||
double weight = 1 / Math.Pow(distance, power);
|
||||
map[dataPoint.Value] = map.ContainsKey(dataPoint.Value) ? map[dataPoint.Value] + weight : weight;
|
||||
}
|
||||
|
||||
return map.Aggregate((x,y)=> x.Value > y.Value ? x : y).Key;
|
||||
}
|
||||
}
|
||||
|
||||
internal class Kriging<T> where T : Distance<T>
|
||||
{
|
||||
private List<T> dataPoints;
|
||||
private double range;
|
||||
private double nugget;
|
||||
|
||||
public Kriging(List<T> dataPoints, double range, double nugget)
|
||||
{
|
||||
this.dataPoints = dataPoints;
|
||||
this.range = range;
|
||||
this.nugget = nugget;
|
||||
}
|
||||
|
||||
public double Interpolate(T targetPoint)
|
||||
{
|
||||
double[] distances = dataPoints.Select(p => targetPoint.DistanceTo(p)).ToArray();
|
||||
//range = distances.Max() - distances.Min();
|
||||
// Calculate weights based on the spherical variogram model
|
||||
double[] weights = distances.Select(d => GaussianVariogram(d)).ToArray();
|
||||
|
||||
// Calculate the interpolated value
|
||||
double interpolatedValue = 0;
|
||||
double totalWeight = 0;
|
||||
|
||||
for (int i = 0; i < dataPoints.Count; i++)
|
||||
{
|
||||
interpolatedValue += weights[i] * dataPoints[i].Value;
|
||||
totalWeight += weights[i];
|
||||
}
|
||||
|
||||
return interpolatedValue / totalWeight;
|
||||
}
|
||||
|
||||
private double SphericalVariogram(double h)
|
||||
{
|
||||
if (h == 0)
|
||||
{
|
||||
return nugget;
|
||||
}
|
||||
else if (h <= range)
|
||||
{
|
||||
return nugget + (1.5 * Math.Pow(h / range, 3) - 2.5 * Math.Pow(h / range, 2) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nugget + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private double GaussianVariogram(double h)
|
||||
{
|
||||
if (h == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nugget + 1 - Math.Exp(-h * h / (range * range));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Point3D : Distance<Point3D>
|
||||
{
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Z { get; set; }
|
||||
|
||||
public override double DistanceTo(Point3D other)
|
||||
{
|
||||
double dx = this.X - other.X;
|
||||
double dy = this.Y - other.Y;
|
||||
double dz = this.Z - other.Z;
|
||||
|
||||
return Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
}
|
||||
|
||||
class Point2D : Distance<Point2D>
|
||||
{
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
|
||||
public override double DistanceTo(Point2D other)
|
||||
{
|
||||
double dx = this.X - other.X;
|
||||
double dy = this.Y - other.Y;
|
||||
|
||||
return Math.Sqrt(dx * dx + dy * dy );
|
||||
}
|
||||
}
|
||||
|
||||
interface IDistance<T>
|
||||
{
|
||||
double DistanceTo(T other);
|
||||
}
|
||||
|
||||
public abstract class Distance<T> : IDistance<T>
|
||||
{
|
||||
public abstract double DistanceTo(T other);
|
||||
public double Value { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -16,7 +16,7 @@ namespace uBIMEarthTools
|
||||
FinishTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
|
||||
TimeSpan = elapsed.TotalMilliseconds
|
||||
};
|
||||
Trace.TraceInformation($"{methodBase.Name} : {elapsed.TotalSeconds}");
|
||||
// Trace.TraceInformation($"{methodBase.Name} : {elapsed.TotalSeconds}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace uBIMEarthTools.Model
|
||||
{
|
||||
@ -63,5 +64,25 @@ namespace uBIMEarthTools.Model
|
||||
/// 当前地层类型
|
||||
/// </summary>
|
||||
public string CurrentType { get; set; }
|
||||
|
||||
public void Interpolation(double plus)
|
||||
{
|
||||
var order = this.ValueList.OrderByDescending(x => x.Point.Z).ToList();
|
||||
List<GeologyLayer> newList = new List<GeologyLayer>();
|
||||
for (int i = 0; i < order.Count - 1; i++)
|
||||
{
|
||||
newList.Add(order[i]);
|
||||
var z = order[i].Point.Z;
|
||||
while (z - plus > order[i + 1].Point.Z)
|
||||
{
|
||||
z = z - plus;
|
||||
GeologyLayer geologyLayer = new GeologyLayer(order[i].Type, new Autodesk.Revit.DB.XYZ(order[i].Point.X, order[i].Point.Y, z));
|
||||
newList.Add(geologyLayer);
|
||||
}
|
||||
}
|
||||
|
||||
this.ValueList = newList;
|
||||
EndIndex = ValueList.Count - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,19 +78,27 @@ namespace uBIMEarthTools.Utils
|
||||
/// <returns></returns>
|
||||
public static bool IsCollinear(TriangleNet.Topology.Triangle triangle)
|
||||
{
|
||||
XYZ p0 = new XYZ(triangle.GetVertex(0).X, triangle.GetVertex(0).Y, 0);
|
||||
XYZ p1 = new XYZ(triangle.GetVertex(1).X, triangle.GetVertex(1).Y, 0);
|
||||
XYZ p2 = new XYZ(triangle.GetVertex(2).X, triangle.GetVertex(2).Y, 0);
|
||||
Line line1 = Line.CreateUnbound(p0, p1 - p0);
|
||||
Line line2 = Line.CreateUnbound(p1, p2 - p1);
|
||||
Line line3 = Line.CreateUnbound(p2, p0 - p2);
|
||||
double d1 = line1.Project(p2).Distance / p0.DistanceTo(p1);
|
||||
double d2 = line2.Project(p0).Distance / p1.DistanceTo(p2);
|
||||
double d3 = line3.Project(p1).Distance / p2.DistanceTo(p0);
|
||||
if (Math.Min(Math.Min(d1, d2), d3) < 0.02)
|
||||
try
|
||||
{
|
||||
XYZ p0 = new XYZ(triangle.GetVertex(0).X, triangle.GetVertex(0).Y, 0);
|
||||
XYZ p1 = new XYZ(triangle.GetVertex(1).X, triangle.GetVertex(1).Y, 0);
|
||||
XYZ p2 = new XYZ(triangle.GetVertex(2).X, triangle.GetVertex(2).Y, 0);
|
||||
Line line1 = Line.CreateUnbound(p0, p1 - p0);
|
||||
Line line2 = Line.CreateUnbound(p1, p2 - p1);
|
||||
Line line3 = Line.CreateUnbound(p2, p0 - p2);
|
||||
double d1 = line1.Project(p2).Distance / p0.DistanceTo(p1);
|
||||
double d2 = line2.Project(p0).Distance / p1.DistanceTo(p2);
|
||||
double d3 = line3.Project(p1).Distance / p2.DistanceTo(p0);
|
||||
if (Math.Min(Math.Min(d1, d2), d3) < 0.02)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -20,6 +20,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EPPlus" Version="5.6.4" />
|
||||
<PackageReference Include="HelixToolkit.Wpf.SharpDX" Version="2.24.0" />
|
||||
<PackageReference Include="MethodTimer.Fody" Version="3.2.0" />
|
||||
<PackageReference Include="NPOI" Version="2.5.5" />
|
||||
<PackageReference Include="RevitSDK2017" Version="1.0.0" />
|
||||
|
Loading…
Reference in New Issue
Block a user