Showing preview only (1,038K chars total). Download the full file or copy to clipboard to get everything.
Repository: RiSearcher/GeometRi.CSharp
Branch: master
Commit: 32c3d6c4f0e8
Files: 74
Total size: 1000.7 KB
Directory structure:
gitextract_h_mvhxyk/
├── .gitattributes
├── .gitignore
├── GeometRi/
│ ├── AABB.cs
│ ├── AbstractClass.cs
│ ├── Box3d.cs
│ ├── Circle3D.cs
│ ├── ConvexPolyhedron.cs
│ ├── Coord3D.cs
│ ├── Ellipse.cs
│ ├── Ellipsoid.cs
│ ├── GeometRi.csproj
│ ├── GeometRi3D.cs
│ ├── Interface.cs
│ ├── Line3D.cs
│ ├── Matrix3D.cs
│ ├── Plane3D.cs
│ ├── Point3D.cs
│ ├── Quaternion.cs
│ ├── Ray3D.cs
│ ├── Rotation.cs
│ ├── Segment3D.cs
│ ├── Sphere.cs
│ ├── Tetrahedron.cs
│ ├── Triangle.cs
│ └── Vector3D.cs
├── GeometRi.Benchmarks/
│ ├── GeometRi.Benchmarks.csproj
│ ├── Program.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ └── app.config
├── GeometRi.Example/
│ ├── GeometRi.Example.csproj
│ ├── Program.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ └── app.config
├── GeometRi.Example.FSharp/
│ ├── App.config
│ ├── AssemblyInfo.fs
│ ├── GeometRi.Example.FSharp.fsproj
│ ├── Program.fs
│ └── packages.config
├── GeometRi.Tests/
│ ├── AABBTest.cs
│ ├── BoundingBoxTest.cs
│ ├── Box3dTest.cs
│ ├── CircleTest.cs
│ ├── ConvexPolyhedronTest.cs
│ ├── CoordTransformTest.cs
│ ├── CoplanarityTest.cs
│ ├── EllipseTest.cs
│ ├── EllipsoidTest.cs
│ ├── GeometRi.Tests.csproj
│ ├── Line3DTest.cs
│ ├── Matrix3dTest.cs
│ ├── NormalizeTest.cs
│ ├── OtherTest.cs
│ ├── Plane3dTest.cs
│ ├── Point3DTest.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── QuaternionTest.cs
│ ├── Ray3DTest.cs
│ ├── ReflectTest.cs
│ ├── RelativeToleranceTest.cs
│ ├── RotateTest.cs
│ ├── RotationTest.cs
│ ├── Segment3dTest.cs
│ ├── SphereTest.cs
│ ├── TetrahedronTest.cs
│ ├── TranslateTest.cs
│ ├── TriangleIntersectionWithLineSegmentTests.cs
│ ├── TriangleTest.cs
│ ├── Vector3dTest.cs
│ └── packages.config
├── GeometRi.sln
├── LICENSE.txt
├── README.md
├── ReleaseNotes.md
└── ToDo.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
[Xx]64/
[Xx]86/
[Bb]uild/
bld/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Un-comment the next line if you do not want to checkin
# your web deploy settings because they may include unencrypted
# passwords
#*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directory
AppPackages/
BundleArtifacts/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# LightSwitch generated files
GeneratedArtifacts/
ModelManifest.xml
# Paket dependency manager
.paket/paket.exe
# FAKE - F# Make
.fake/
================================================
FILE: GeometRi/AABB.cs
================================================
using System;
using static System.Math;
using System.Collections.Generic;
namespace GeometRi
{
/// <summary>
/// Axis aligned 3D box, can be degenerated with one or more dimensions equal 0. Defined only in Global CS.
/// </summary>
#if NET20_OR_GREATER
[Serializable]
#endif
public class AABB : FiniteObject, IFiniteObject
{
private Point3d _center;
private double _lx, _ly, _lz;
private List<Point3d> _list_p = null;
private List<Triangle> _list_t = null;
private List<Segment3d> _list_e = null;
private List<Plane3d> _list_plane = null;
private static object _lock = new object();
#region "Constructors"
/// <summary>
/// Default constructor, initializes box in the origin of the global coordinate system aligned with coordinate axes.
/// </summary>
public AABB(Point3d center, double lx, double ly, double lz)
{
_center = center.ConvertToGlobal().Copy();
_lx = lx;
_ly = ly;
_lz = lz;
}
/// <summary>
/// Initializes unit box in the origin of the global coordinate system aligned with coordinate axes.
/// </summary>
public AABB()
{
_center = new Point3d();
_lx = _ly = _lz = 1.0;
}
/// <summary>
/// Initializes axis aligned box by two points.
/// </summary>
public AABB(Point3d Pmin, Point3d Pmax)
{
Point3d p1 = Pmin.ConvertToGlobal();
Point3d p2 = Pmax.ConvertToGlobal();
_center = (p1 + p2) / 2;
_lx = Abs(p2.X - p1.X);
_ly = Abs(p2.Y - p1.Y);
_lz = Abs(p2.Z - p1.Z);
}
#endregion
/// <summary>
/// Creates copy of the object
/// </summary>
public AABB Copy()
{
return new AABB(_center, _lx, _ly, _lz);
}
#region "Properties"
/// <summary>
/// Center point of the box.
/// </summary>
public Point3d Center
{
get { return _center; }
set
{
_center = value.Copy();
_list_p = null;
_list_t = null;
_list_e = null;
_list_plane = null;
}
}
/// <summary>
/// First dimension.
/// </summary>
public double L1
{
get { return _lx; }
set
{
_lx = value;
_list_p = null;
_list_t = null;
_list_e = null;
_list_plane = null;
}
}
/// <summary>
/// Second dimension.
/// </summary>
public double L2
{
get { return _ly; }
set
{
_ly = value;
_list_p = null;
_list_t = null;
_list_e = null;
_list_plane = null;
}
}
/// <summary>
/// Third dimension.
/// </summary>
public double L3
{
get { return _lz; }
set
{
_lz = value;
_list_p = null;
_list_t = null;
_list_e = null;
_list_plane = null;
}
}
public double Xmin { get { return _center.X - _lx / 2; } }
public double Xmax { get { return _center.X + _lx / 2; } }
public double Ymin { get { return _center.Y - _ly / 2; } }
public double Ymax { get { return _center.Y + _ly / 2; } }
public double Zmin { get { return _center.Z - _lz / 2; } }
public double Zmax { get { return _center.Z + _lz / 2; } }
/// <summary>
/// Orientation of the first dimension of the box.
/// </summary>
public Vector3d V1
{
get { return Coord3d.GlobalCS.Xaxis; }
}
/// <summary>
/// Orientation of the second dimension of the box.
/// </summary>
public Vector3d V2
{
get { return Coord3d.GlobalCS.Yaxis; }
}
/// <summary>
/// Orientation of the third dimension of the box.
/// </summary>
public Vector3d V3
{
get { return Coord3d.GlobalCS.Zaxis; }
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P1
{
get
{
return new Point3d(_center.X - 0.5 * _lx, _center.Y - 0.5 * _ly, _center.Z - 0.5 * _lz);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P2
{
get
{
return new Point3d(_center.X + 0.5 * _lx, _center.Y - 0.5 * _ly, _center.Z - 0.5 * _lz);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P3
{
get
{
return new Point3d(_center.X + 0.5 * _lx, _center.Y + 0.5 * _ly, _center.Z - 0.5 * _lz);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P4
{
get
{
return new Point3d(_center.X - 0.5 * _lx, _center.Y + 0.5 * _ly, _center.Z - 0.5 * _lz);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P5
{
get
{
return new Point3d(_center.X - 0.5 * _lx, _center.Y - 0.5 * _ly, _center.Z + 0.5 * _lz);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P6
{
get
{
return new Point3d(_center.X + 0.5 * _lx, _center.Y - 0.5 * _ly, _center.Z + 0.5 * _lz);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P7
{
get
{
return new Point3d(_center.X + 0.5 * _lx, _center.Y + 0.5 * _ly, _center.Z + 0.5 * _lz);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P8
{
get
{
return new Point3d(_center.X - 0.5 * _lx, _center.Y + 0.5 * _ly, _center.Z + 0.5 * _lz);
}
}
/// <summary>
/// List of corner points.
/// </summary>
public List<Point3d> ListOfPoints
{
get
{
lock (_lock)
{
if (_list_p == null)
{
_list_p = new List<Point3d> { P1, P2, P3, P4, P5, P6, P7, P8 };
return _list_p;
}
else
{
return _list_p;
}
}
}
}
/// <summary>
/// List of triangles forming the box's surface
/// </summary>
public List<Triangle> ListOfTriangles
{
get
{
lock (_lock)
{
if (_list_t == null)
{
Point3d P1 = this.P1;
Point3d P2 = this.P2;
Point3d P3 = this.P3;
Point3d P4 = this.P4;
Point3d P5 = this.P5;
Point3d P6 = this.P6;
Point3d P7 = this.P7;
Point3d P8 = this.P8;
_list_t = new List<Triangle> { };
_list_t.Add(new Triangle(P1, P3, P2));
_list_t.Add(new Triangle(P1, P4, P3));
_list_t.Add(new Triangle(P1, P2, P6));
_list_t.Add(new Triangle(P1, P6, P5));
_list_t.Add(new Triangle(P2, P3, P7));
_list_t.Add(new Triangle(P2, P7, P6));
_list_t.Add(new Triangle(P3, P4, P8));
_list_t.Add(new Triangle(P3, P8, P7));
_list_t.Add(new Triangle(P4, P1, P5));
_list_t.Add(new Triangle(P4, P5, P8));
_list_t.Add(new Triangle(P5, P6, P7));
_list_t.Add(new Triangle(P5, P7, P8));
return _list_t;
}
else
{
return _list_t;
}
}
}
}
/// <summary>
/// List of planes forming the box's surface
/// </summary>
public List<Plane3d> ListOfPlanes
{
get
{
lock (_lock)
{
if (_list_plane == null)
{
_list_plane = new List<Plane3d> { };
_list_plane.Add(new Plane3d(P1, -V1));
_list_plane.Add(new Plane3d(P2, V1));
_list_plane.Add(new Plane3d(P1, -V2));
_list_plane.Add(new Plane3d(P4, V2));
_list_plane.Add(new Plane3d(P1, -V3));
_list_plane.Add(new Plane3d(P5, V3));
return _list_plane;
}
else
{
return _list_plane;
}
}
}
}
/// <summary>
/// List of edges forming the box
/// </summary>
public List<Segment3d> ListOfEdges
{
get
{
lock (_lock)
{
if (_list_e == null)
{
_list_e = new List<Segment3d> { };
_list_e.Add(new Segment3d(P1, P2));
_list_e.Add(new Segment3d(P2, P3));
_list_e.Add(new Segment3d(P3, P4));
_list_e.Add(new Segment3d(P4, P1));
_list_e.Add(new Segment3d(P5, P6));
_list_e.Add(new Segment3d(P6, P7));
_list_e.Add(new Segment3d(P7, P8));
_list_e.Add(new Segment3d(P8, P5));
_list_e.Add(new Segment3d(P1, P5));
_list_e.Add(new Segment3d(P2, P6));
_list_e.Add(new Segment3d(P3, P7));
_list_e.Add(new Segment3d(P4, P8));
return _list_e;
}
else
{
return _list_e;
}
}
}
}
/// <summary>
/// Volume of the box.
/// </summary>
public double Volume
{
get { return _lx * _ly * _lz; }
}
/// <summary>
/// Surface area of the box.
/// </summary>
public double Area
{
get { return 2.0 * (_lx * _ly + _lx * _lz + _ly * _lz); }
}
/// <summary>
/// Length of the box diagonal.
/// </summary>
public double Diagonal
{
get { return Sqrt(_lx * _lx + _ly * _ly + _lz * _lz); }
}
/// <summary>
/// True if box is axis aligned
/// </summary>
public bool IsAxisAligned
{
get { return true; }
}
#endregion
#region "BoundingBox"
/// <summary>
/// Return minimum bounding box.
/// </summary>
public Box3d MinimumBoundingBox
{
get { return new Box3d(_center, _lx, _ly, _lz); }
}
/// <summary>
/// Return Axis Aligned Bounding Box (AABB) in given coordinate system.
/// </summary>
public Box3d BoundingBox(Coord3d coord = null)
{
coord = (coord == null) ? Coord3d.GlobalCS : coord;
Point3d c = _center.ConvertTo(coord);
double mx = c.X;
double my = c.Y;
double mz = c.Z;
foreach (Point3d p in this.ListOfPoints)
{
Point3d t = p.ConvertTo(coord);
if (t.X < mx) mx = t.X;
if (t.Y < my) my = t.Y;
if (t.Z < mz) mz = t.Z;
}
return new Box3d(c, 2.0 * (c.X - mx), 2.0 * (c.Y - my), 2.0 * (c.Z - mz), coord);
}
/// <summary>
/// Return bounding sphere.
/// </summary>
public Sphere BoundingSphere
{
get
{
double r = 0.5 * Sqrt(_lx * _lx + _ly * _ly + _lz * _lz);
return new Sphere(this.Center, r);
}
}
#endregion
/// <summary>
/// Return Axis Aligned Bounding Box (AABB) for a cloud of points.
/// </summary>
public static AABB BoundingBox(IEnumerable<Point3d> points)
{
double maxx = double.NegativeInfinity;
double maxy = double.NegativeInfinity;
double maxz = double.NegativeInfinity;
double minx = double.PositiveInfinity;
double miny = double.PositiveInfinity;
double minz = double.PositiveInfinity;
foreach (Point3d p in points)
{
Point3d t = p.ConvertToGlobal();
if (t.X > maxx) { maxx = t.X; }
if (t.Y > maxy) { maxy = t.Y; }
if (t.Z > maxz) { maxz = t.Z; }
if (t.X < minx) { minx = t.X; }
if (t.Y < miny) { miny = t.Y; }
if (t.Z < minz) { minz = t.Z; }
}
return new AABB(new Point3d(0.5 * (maxx + minx), 0.5 * (maxy + miny), 0.5 * (maxz + minz)), maxx - minx, maxy - miny, maxz - minz);
}
/// <summary>
/// Return union of two AABBs>
public static AABB Union(AABB box1, AABB box2)
{
double maxx = Max(box1.Xmax, box2.Xmax);
double maxy = Max(box1.Ymax, box2.Ymax);
double maxz = Max(box1.Zmax, box2.Zmax);
double minx = Min(box1.Xmin, box2.Xmin);
double miny = Min(box1.Ymin, box2.Ymin);
double minz = Min(box1.Zmin, box2.Zmin);
return new AABB(new Point3d(0.5 * (maxx + minx), 0.5 * (maxy + miny), 0.5 * (maxz + minz)), maxx - minx, maxy - miny, maxz - minz);
}
#region "Intersection"
/// <summary>
/// Get intersection of line with box.
/// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Line3d l)
{
return _line_intersection(l, double.NegativeInfinity, double.PositiveInfinity);
}
/// <summary>
/// Get intersection of ray with box.
/// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Ray3d r)
{
return _line_intersection(r.ToLine, 0.0, double.PositiveInfinity);
}
/// <summary>
/// Get intersection of segment with box.
/// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Segment3d s)
{
return _line_intersection(s.Line, 0.0, s.Length);
}
/// <summary>
/// Check intersection of box with triangle
/// </summary>
public bool Intersects(Triangle t)
{
if (t.A.BelongsTo(this) || t.B.BelongsTo(this) || t.C.BelongsTo(this))
{
return true;
}
foreach (Triangle bt in this.ListOfTriangles)
{
if (bt.Intersects(t)) return true;
}
return false;
}
/// <summary>
/// Check intersection of two boxes (only for AABB boxes, no check is performed for speed)
/// </summary>
public bool Intersects(Box3d box)
{
bool x = Abs(this._center.X - box._center.X) <= 0.5 * (this.L1 + box.L1) ? true : false;
bool y = Abs(this._center.Y - box._center.Y) <= 0.5 * (this.L2 + box.L2) ? true : false;
bool z = Abs(this._center.Z - box._center.Z) <= 0.5 * (this.L3 + box.L3) ? true : false;
return x && y && z;
}
/// <summary>
/// Check intersection of two AABB
/// </summary>
public bool Intersects(AABB box)
{
bool x = Abs(this._center.X - box._center.X) <= 0.5 * (this.L1 + box.L1) ? true : false;
bool y = Abs(this._center.Y - box._center.Y) <= 0.5 * (this.L2 + box.L2) ? true : false;
bool z = Abs(this._center.Z - box._center.Z) <= 0.5 * (this.L3 + box.L3) ? true : false;
return x && y && z;
}
/// <summary>
/// Intersection check between circle and box
/// </summary>
public bool Intersects(Circle3d c)
{
//if (c.Center.IsInside(this)) return true;
double dist = c._point.DistanceTo(this);
if (dist > c.R) return false;
if (dist < GeometRi3D.Tolerance) return true;
foreach (Triangle triangle in ListOfTriangles)
{
if (c.Intersects(triangle)) return true;
}
return false;
}
/// <summary>
/// Check if AABB is located inside box.
/// </summary>
public bool IsInside(Box3d box)
{
foreach (Point3d p in ListOfPoints)
{
if (!p.IsInside(box)) return false;
}
return true;
}
/// <summary>
/// Check if AABB is located inside box.
/// </summary>
public bool IsInside(AABB box)
{
foreach (Point3d p in ListOfPoints)
{
if (!p.IsInside(box)) return false;
}
return true;
}
/// <summary>
/// Intersection of two AABB (null for non-intersecting AABB)
/// </summary>
public AABB IntersectionWith(AABB box)
{
double x1min = this._center.X - 0.5 * this.L1;
double x1max = this._center.X + 0.5 * this.L1;
double y1min = this._center.Y - 0.5 * this.L2;
double y1max = this._center.Y + 0.5 * this.L2;
double z1min = this._center.Z - 0.5 * this.L3;
double z1max = this._center.Z + 0.5 * this.L3;
double x2min = box._center.X - 0.5 * box.L1;
double x2max = box._center.X + 0.5 * box.L1;
double y2min = box._center.Y - 0.5 * box.L2;
double y2max = box._center.Y + 0.5 * box.L2;
double z2min = box._center.Z - 0.5 * box.L3;
double z2max = box._center.Z + 0.5 * box.L3;
double xmin, xmax, ymin, ymax, zmin, zmax;
xmin = Max(x1min, x2min);
xmax = Min(x1max, x2max);
if (xmax >= xmin)
{
ymin = Max(y1min, y2min);
ymax = Min(y1max, y2max);
if (ymax >= ymin)
{
zmin = Max(z1min, z2min);
zmax = Min(z1max, z2max);
if (zmax >= zmin)
{
return new AABB(new Point3d(xmin, ymin, zmin), new Point3d(xmax, ymax, zmax));
}
else
{
return null;
}
}
else
{
return null;
}
}
else
{
return null;
}
}
private object _line_intersection(Line3d l, double t0, double t1)
{
// Smith's algorithm:
// "An Efficient and Robust Ray–Box Intersection Algorithm"
// Amy Williams, Steve Barrus, R. Keith Morley, Peter Shirley
// http://www.cs.utah.edu/~awilliam/box/box.pdf
// Modified to allow tolerance based checks
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.Diagonal;
GeometRi3D.UseAbsoluteTolerance = true;
object result = _line_intersection(l, t0, t1);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
// Define local CS aligned with box
Coord3d local_CS = this.LocalCoord();
Point3d Pmin = this.P1.ConvertTo(local_CS);
Point3d Pmax = this.P7.ConvertTo(local_CS);
l = new Line3d(l.Point.ConvertTo(local_CS), l.Direction.ConvertTo(local_CS).Normalized);
double tmin, tmax, tymin, tymax, tzmin, tzmax;
double divx = 1 / l.Direction.X;
if (divx >= 0)
{
tmin = (Pmin.X - l.Point.X) * divx;
tmax = (Pmax.X - l.Point.X) * divx;
}
else
{
tmin = (Pmax.X - l.Point.X) * divx;
tmax = (Pmin.X - l.Point.X) * divx;
}
double divy = 1 / l.Direction.Y;
if (divy >= 0)
{
tymin = (Pmin.Y - l.Point.Y) * divy;
tymax = (Pmax.Y - l.Point.Y) * divy;
}
else
{
tymin = (Pmax.Y - l.Point.Y) * divy;
tymax = (Pmin.Y - l.Point.Y) * divy;
}
if (GeometRi3D.Greater(tmin, tymax) || GeometRi3D.Greater(tymin, tmax))
return null;
if (GeometRi3D.Greater(tymin, tmin))
tmin = tymin;
if (GeometRi3D.Smaller(tymax, tmax))
tmax = tymax;
double divz = 1 / l.Direction.Z;
if (divz >= 0)
{
tzmin = (Pmin.Z - l.Point.Z) * divz;
tzmax = (Pmax.Z - l.Point.Z) * divz;
}
else
{
tzmin = (Pmax.Z - l.Point.Z) * divz;
tzmax = (Pmin.Z - l.Point.Z) * divz;
}
if (GeometRi3D.Greater(tmin, tzmax) || GeometRi3D.Greater(tzmin, tmax))
return null;
if (GeometRi3D.Greater(tzmin, tmin))
tmin = tzmin;
if (GeometRi3D.Smaller(tzmax, tmax))
tmax = tzmax;
// Now check the overlapping portion of the segments
// This part is missing in the original algorithm
if (GeometRi3D.Greater(tmin, t1))
return null;
if (GeometRi3D.Smaller(tmax, t0))
return null;
if (GeometRi3D.Smaller(tmin, t0))
tmin = t0;
if (GeometRi3D.Greater(tmax, t1))
tmax = t1;
if (GeometRi3D.AlmostEqual(tmin, tmax))
{
return l.Point.Translate(tmin * l.Direction);
}
else
{
return new Segment3d(l.Point.Translate(tmin * l.Direction), l.Point.Translate(tmax * l.Direction));
}
}
#endregion
/// <summary>
/// Local coordinate system with origin in box's center and aligned with box
/// </summary>
public Coord3d LocalCoord()
{
return new Coord3d(this._center, V1, V2);
}
/// <summary>
/// Point on box (including interior points) closest to target point "p".
/// </summary>
public Point3d ClosestPoint(Point3d p)
{
p = p.ConvertToGlobal();
double x = GeometRi3D.Clamp(p.X, this._center.X - _lx / 2, this._center.X + _lx / 2);
double y = GeometRi3D.Clamp(p.Y, this._center.Y - _ly / 2, this._center.Y + _ly / 2);
double z = GeometRi3D.Clamp(p.Z, this._center.Z - _lz / 2, this._center.Z + _lz / 2);
return new Point3d(x, y, z);
}
/// <summary>
/// Distance from box to point (zero will be returned for point located inside box)
/// </summary>
public double DistanceTo(Point3d p)
{
return ClosestPoint(p).DistanceTo(p);
}
/// <summary>
/// Distance between two AABB
/// </summary>
public double DistanceTo(AABB box)
{
double dx = Abs(_center.X - box._center.X) - 0.5 * (_lx + box._lx);
double dy = Abs(_center.Y - box._center.Y) - 0.5 * (_ly + box._ly);
double dz = Abs(_center.Z - box._center.Z) - 0.5 * (_lz + box._lz);
if (dx < 0) { dx = 0; }
if (dy < 0) { dy = 0; }
if (dz < 0) { dz = 0; }
return Sqrt(dx * dx + dy * dy + dz * dz);
}
/// <summary>
/// Shortest distance from box to sphere
/// </summary>
public double DistanceTo(Sphere s)
{
Point3d p = this.ClosestPoint(s._point);
double dist = p.DistanceTo(s._point);
return dist <= s.R ? 0.0 : dist - s.R;
}
/// <summary>
/// Shortest distance from box to circle
/// </summary>
public double DistanceTo(Circle3d c)
{
if (c._point.IsInside(this))
{
return 0;
}
double min_dist = Double.PositiveInfinity;
foreach (Triangle triangle in ListOfTriangles)
{
double dist = c.DistanceTo(triangle);
if (dist <= GeometRi3D.Tolerance) return 0;
if (dist < min_dist) min_dist = dist;
}
return min_dist;
}
internal override int _PointLocation(Point3d p)
{
Coord3d coord = this.LocalCoord();
p = p.ConvertTo(coord);
if (GeometRi3D.UseAbsoluteTolerance)
{
if ((Abs(p.X) - L1 / 2) <= GeometRi3D.Tolerance && (Abs(p.Y) - L2 / 2) <= GeometRi3D.Tolerance && (Abs(p.Z) - L3 / 2) <= GeometRi3D.Tolerance)
{
if ((Abs(p.X) - L1 / 2) < -GeometRi3D.Tolerance && (Abs(p.Y) - L2 / 2) < -GeometRi3D.Tolerance && (Abs(p.Z) - L3 / 2) < -GeometRi3D.Tolerance)
{
return 1; // Point is strictly inside box
}
else
{
return 0; // Point is on boundary
}
}
else
{
return -1; // Point is outside
}
}
else
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.Diagonal;
GeometRi3D.UseAbsoluteTolerance = true;
int result = this._PointLocation(p);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
}
#region "TranslateRotateReflect"
/// <summary>
/// Translate box by a vector
/// </summary>
public AABB Translate(Vector3d v)
{
return new AABB(_center.Translate(v), _lx, _ly, _lz);
}
/// <summary>
/// Reflect box in given point
/// <para>The order of corner points will be changed during reflection operation.</para>
/// </summary>
public virtual AABB ReflectIn(Point3d p)
{
Point3d new_center = this.Center.ReflectIn(p);
return new AABB(new_center, _lx, _ly, _lz);
}
/// <summary>
/// Scale box relative to given point
/// </summary>
public virtual AABB Scale(double scale, Point3d scaling_center)
{
Point3d new_center = scaling_center + scale * (this._center - scaling_center);
return new AABB(new_center, scale * _lx, scale * _ly, scale * _lz);
}
#endregion
/// <summary>
/// Determines whether two objects are equal.
/// </summary>
public override bool Equals(object obj)
{
if (obj == null || (!object.ReferenceEquals(this.GetType(), obj.GetType())))
{
return false;
}
AABB b = (AABB)obj;
if (GeometRi3D.UseAbsoluteTolerance)
{
return this._center == b._center &&
GeometRi3D.AlmostEqual(L1, b.L1) &&
GeometRi3D.AlmostEqual(L2, b.L2) &&
GeometRi3D.AlmostEqual(L3, b.L3);
}
else
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.Diagonal;
GeometRi3D.UseAbsoluteTolerance = true;
bool result = this.Equals(b);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
}
/// <summary>
/// Returns the hashcode for the object.
/// </summary>
public override int GetHashCode()
{
int hash_code = GeometRi3D.HashFunction(_lx.GetHashCode(), _ly.GetHashCode(), _lz.GetHashCode());
return GeometRi3D.HashFunction(_center.GetHashCode(), hash_code);
}
/// <summary>
/// String representation of an object in global coordinate system.
/// </summary>
public override string ToString()
{
return ToString(Coord3d.GlobalCS);
}
/// <summary>
/// String representation of an object in reference coordinate system.
/// </summary>
public string ToString(Coord3d coord)
{
string nl = System.Environment.NewLine;
if (coord == null) { coord = Coord3d.GlobalCS; }
Point3d p = _center.ConvertTo(coord);
string str = string.Format("Box3d (reference coord.sys. ") + coord.Name + "):" + nl;
str += string.Format("Center -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", p.X, p.Y, p.Z) + nl;
str += string.Format("Lx, Ly, Lz -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", _lx, _ly, _lz) + nl;
return str;
}
// Operators overloads
//-----------------------------------------------------------------
public static bool operator ==(AABB b1, AABB b2)
{
if (object.ReferenceEquals(b1, null))
return object.ReferenceEquals(b2, null);
return b1.Equals(b2);
}
public static bool operator !=(AABB b1, AABB b2)
{
if (object.ReferenceEquals(b1, null))
return !object.ReferenceEquals(b2, null);
return !b1.Equals(b2);
}
}
}
================================================
FILE: GeometRi/AbstractClass.cs
================================================
using System;
using static System.Math;
using System.Collections.Generic;
namespace GeometRi
{
#if NET20_OR_GREATER
[Serializable]
#endif
abstract public class FiniteObject
{
abstract internal int _PointLocation(Point3d p);
}
#if NET20_OR_GREATER
[Serializable]
#endif
abstract public class PlanarFiniteObject : FiniteObject
{
abstract internal Plane3d Plane { get; }
}
#if NET20_OR_GREATER
[Serializable]
#endif
abstract public class LinearFiniteObject : FiniteObject
{
abstract internal Line3d Line { get; }
abstract internal Vector3d Vector { get; }
abstract internal Ray3d Ray { get; }
}
}
================================================
FILE: GeometRi/Box3d.cs
================================================
using System;
using static System.Math;
using System.Collections.Generic;
namespace GeometRi
{
/// <summary>
/// Arbitrary oriented 3D box, can be degenerated with one or more dimensions equal 0.
/// </summary>
#if NET20_OR_GREATER
[Serializable]
#endif
public class Box3d : FiniteObject, IFiniteObject
{
internal Point3d _center;
internal double _lx, _ly, _lz;
internal Vector3d _v1, _v2, _v3;
private Rotation _r;
private Coord3d _local_coord = null;
private List<Point3d> _list_p = null;
private List<Triangle> _list_t = null;
private List<Segment3d> _list_e = null;
private List<Plane3d> _list_plane = null;
private static object _lock = new object();
#region "Constructors"
/// <summary>
/// Default constructor, initializes box in the origin of the global coordinate system aligned with coordinate axes.
/// </summary>
public Box3d(Point3d center, double lx, double ly, double lz)
{
_center = center.Copy();
_lx = lx;
_ly = ly;
_lz = lz;
_v1 = new Vector3d(1, 0, 0);
_v2 = new Vector3d(0, 1, 0);
_v3 = new Vector3d(0, 0, 1);
_r = new Rotation();
_local_coord = new Coord3d(_center, _r.ConvertToGlobal().ToRotationMatrix.Transpose());
}
/// <summary>
/// Initializes unit box in the origin of the reference coordinate system aligned with coordinate axes.
/// </summary>
/// <param name="coord">Reference coordinate system.</param>
public Box3d(Coord3d coord = null)
{
_center = new Point3d(coord);
_lx = _ly = _lz = 1.0;
_v1 = new Vector3d(1, 0, 0, coord);
_v2 = new Vector3d(0, 1, 0, coord);
_v3 = new Vector3d(0, 0, 1, coord);
_r = new Rotation(coord);
if (coord != null)
{
// do not set local_coord for box aligned with global CS
_local_coord = new Coord3d(_center, _r.ConvertToGlobal().ToRotationMatrix.Transpose());
}
}
/// <summary>
/// Initializes box with specified dimensions and orientation defined by rotation object.
/// </summary>
/// <param name="center">Center point of the box.</param>
/// <param name="lx">First dimension.</param>
/// <param name="ly">Second dimension.</param>
/// <param name="lz">Third dimension.</param>
/// <param name="r">Orientation of the box, defined as rotation from axis aligned position (in global CS) to final position.</param>
public Box3d(Point3d center, double lx, double ly, double lz, Rotation r)
{
_center = center.Copy();
_lx = lx;
_ly = ly;
_lz = lz;
_r = r.Copy();
_v1 = _r.ConvertToGlobal().ToRotationMatrix.Column1;
_v2 = _r.ConvertToGlobal().ToRotationMatrix.Column2;
_v3 = _r.ConvertToGlobal().ToRotationMatrix.Column3;
_local_coord = new Coord3d(_center, _r.ConvertToGlobal().ToRotationMatrix.Transpose());
}
/// <summary>
/// Initializes axis aligned box in local coordinate system.
/// </summary>
/// <param name="center">Center point of the box.</param>
/// <param name="lx">First dimension.</param>
/// <param name="ly">Second dimension.</param>
/// <param name="lz">Third dimension.</param>
/// <param name="coord">Local coordinate system.</param>
public Box3d(Point3d center, double lx, double ly, double lz, Coord3d coord)
{
_center = center.Copy();
_lx = lx;
_ly = ly;
_lz = lz;
_v1 = new Vector3d(1, 0, 0, coord);
_v2 = new Vector3d(0, 1, 0, coord);
_v3 = new Vector3d(0, 0, 1, coord);
_r = new Rotation(coord);
_local_coord = new Coord3d(_center, _r.ConvertToGlobal().ToRotationMatrix.Transpose());
}
/// <summary>
/// Initializes axis aligned box by two points.
/// </summary>
/// <param name="p_min">Minimum corner of the box</param>
/// <param name="p_max">Maximum corner of the box</param>
public Box3d(Point3d p_min, Point3d p_max)
{
_center = (p_min + p_max) / 2;
Vector3d v = new Vector3d(p_min, p_max).ConvertToGlobal();
_lx = v.X;
_ly = v.Y;
_lz = v.Z;
_v1 = new Vector3d(1, 0, 0);
_v2 = new Vector3d(0, 1, 0);
_v3 = new Vector3d(0, 0, 1);
_r = new Rotation();
_local_coord = new Coord3d(_center, _r.ConvertToGlobal().ToRotationMatrix.Transpose());
}
#endregion
/// <summary>
/// Creates copy of the object
/// </summary>
public Box3d Copy()
{
return new Box3d(_center, _lx, _ly, _lz, _r);
}
#region "Properties"
/// <summary>
/// Center point of the box.
/// </summary>
public Point3d Center
{
get { return _center.Copy(); }
set {
_center = value.Copy();
_list_p = null;
_list_t = null;
_list_e = null;
_list_plane = null;
_local_coord = new Coord3d(_center, _r.ConvertToGlobal().ToRotationMatrix.Transpose());
}
}
/// <summary>
/// First dimension.
/// </summary>
public double L1
{
get { return _lx; }
set {
_lx = value;
_list_p = null;
_list_t = null;
_list_e = null;
_list_plane = null;
}
}
/// <summary>
/// Second dimension.
/// </summary>
public double L2
{
get { return _ly; }
set {
_ly = value;
_list_p = null;
_list_t = null;
_list_e = null;
_list_plane = null;
}
}
/// <summary>
/// Third dimension.
/// </summary>
public double L3
{
get { return _lz; }
set {
_lz = value;
_list_p = null;
_list_t = null;
_list_e = null;
_list_plane = null;
}
}
/// <summary>
/// Orientation of the first dimension of the box.
/// </summary>
public Vector3d V1
{
get { return _v1; }
}
/// <summary>
/// Orientation of the second dimension of the box.
/// </summary>
public Vector3d V2
{
get { return _v2; }
}
/// <summary>
/// Orientation of the third dimension of the box.
/// </summary>
public Vector3d V3
{
get { return _v3; }
}
/// <summary>
/// Orientation of the box, defined as rotation from axis aligned position (in global CS) to final position.
/// </summary>
public Rotation Orientation
{
get { return _r.Copy(); }
set {
_r = value.Copy();
_v1 = _r.ConvertToGlobal().ToRotationMatrix.Column1;
_v2 = _r.ConvertToGlobal().ToRotationMatrix.Column2;
_v3 = _r.ConvertToGlobal().ToRotationMatrix.Column3;
_list_p = null;
_list_t = null;
_list_e = null;
_list_plane = null;
_local_coord = new Coord3d(_center, _r.ConvertToGlobal().ToRotationMatrix.Transpose());
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P1
{
get
{
return _center.ConvertToGlobal() + 0.5 * (
-_lx * _r.ConvertToGlobal().ToRotationMatrix.Column1.ToPoint
- _ly * _r.ConvertToGlobal().ToRotationMatrix.Column2.ToPoint
- _lz * _r.ConvertToGlobal().ToRotationMatrix.Column3.ToPoint);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P2
{
get
{
return _center.ConvertToGlobal() + 0.5 * (
+_lx * _r.ConvertToGlobal().ToRotationMatrix.Column1.ToPoint
- _ly * _r.ConvertToGlobal().ToRotationMatrix.Column2.ToPoint
- _lz * _r.ConvertToGlobal().ToRotationMatrix.Column3.ToPoint);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P3
{
get
{
return _center.ConvertToGlobal() + 0.5 * (
+_lx * _r.ConvertToGlobal().ToRotationMatrix.Column1.ToPoint
+ _ly * _r.ConvertToGlobal().ToRotationMatrix.Column2.ToPoint
- _lz * _r.ConvertToGlobal().ToRotationMatrix.Column3.ToPoint);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P4
{
get
{
return _center.ConvertToGlobal() + 0.5 * (
-_lx * _r.ConvertToGlobal().ToRotationMatrix.Column1.ToPoint
+ _ly * _r.ConvertToGlobal().ToRotationMatrix.Column2.ToPoint
- _lz * _r.ConvertToGlobal().ToRotationMatrix.Column3.ToPoint);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P5
{
get
{
return _center.ConvertToGlobal() + 0.5 * (
-_lx * _r.ConvertToGlobal().ToRotationMatrix.Column1.ToPoint
- _ly * _r.ConvertToGlobal().ToRotationMatrix.Column2.ToPoint
+ _lz * _r.ConvertToGlobal().ToRotationMatrix.Column3.ToPoint);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P6
{
get
{
return _center.ConvertToGlobal() + 0.5 * (
+_lx * _r.ConvertToGlobal().ToRotationMatrix.Column1.ToPoint
- _ly * _r.ConvertToGlobal().ToRotationMatrix.Column2.ToPoint
+ _lz * _r.ConvertToGlobal().ToRotationMatrix.Column3.ToPoint);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P7
{
get
{
return _center.ConvertToGlobal() + 0.5 * (
+_lx * _r.ConvertToGlobal().ToRotationMatrix.Column1.ToPoint
+ _ly * _r.ConvertToGlobal().ToRotationMatrix.Column2.ToPoint
+ _lz * _r.ConvertToGlobal().ToRotationMatrix.Column3.ToPoint);
}
}
/// <summary>
/// Corner point of the box.
/// </summary>
public Point3d P8
{
get
{
return _center.ConvertToGlobal() + 0.5 * (
-_lx * _r.ConvertToGlobal().ToRotationMatrix.Column1.ToPoint
+ _ly * _r.ConvertToGlobal().ToRotationMatrix.Column2.ToPoint
+ _lz * _r.ConvertToGlobal().ToRotationMatrix.Column3.ToPoint);
}
}
/// <summary>
/// List of corner points.
/// </summary>
public List<Point3d> ListOfPoints
{
get
{
lock (_lock)
{
if (_list_p == null)
{
_list_p = new List<Point3d> { P1, P2, P3, P4, P5, P6, P7, P8 };
return _list_p;
}
else
{
return _list_p;
}
}
}
}
/// <summary>
/// List of triangles forming the box's surface
/// </summary>
public List<Triangle> ListOfTriangles
{
get
{
lock (_lock)
{
if (_list_t == null)
{
Point3d P1 = this.P1;
Point3d P2 = this.P2;
Point3d P3 = this.P3;
Point3d P4 = this.P4;
Point3d P5 = this.P5;
Point3d P6 = this.P6;
Point3d P7 = this.P7;
Point3d P8 = this.P8;
_list_t = new List<Triangle> { };
_list_t.Add(new Triangle(P1, P3, P2));
_list_t.Add(new Triangle(P1, P4, P3));
_list_t.Add(new Triangle(P1, P2, P6));
_list_t.Add(new Triangle(P1, P6, P5));
_list_t.Add(new Triangle(P2, P3, P7));
_list_t.Add(new Triangle(P2, P7, P6));
_list_t.Add(new Triangle(P3, P4, P8));
_list_t.Add(new Triangle(P3, P8, P7));
_list_t.Add(new Triangle(P4, P1, P5));
_list_t.Add(new Triangle(P4, P5, P8));
_list_t.Add(new Triangle(P5, P6, P7));
_list_t.Add(new Triangle(P5, P7, P8));
return _list_t;
}
else
{
return _list_t;
}
}
}
}
/// <summary>
/// List of planes forming the box's surface
/// </summary>
public List<Plane3d> ListOfPlanes
{
get
{
lock (_lock)
{
if (_list_plane == null)
{
_list_plane = new List<Plane3d> { };
_list_plane.Add(new Plane3d(P1, -V1));
_list_plane.Add(new Plane3d(P2, V1));
_list_plane.Add(new Plane3d(P1, -V2));
_list_plane.Add(new Plane3d(P4, V2));
_list_plane.Add(new Plane3d(P1, -V3));
_list_plane.Add(new Plane3d(P5, V3));
return _list_plane;
}
else
{
return _list_plane;
}
}
}
}
/// <summary>
/// List of edges forming the box
/// </summary>
public List<Segment3d> ListOfEdges
{
get
{
lock (_lock)
{
if (_list_e == null)
{
_list_e = new List<Segment3d> { };
_list_e.Add(new Segment3d(P1, P2));
_list_e.Add(new Segment3d(P2, P3));
_list_e.Add(new Segment3d(P3, P4));
_list_e.Add(new Segment3d(P4, P1));
_list_e.Add(new Segment3d(P5, P6));
_list_e.Add(new Segment3d(P6, P7));
_list_e.Add(new Segment3d(P7, P8));
_list_e.Add(new Segment3d(P8, P5));
_list_e.Add(new Segment3d(P1, P5));
_list_e.Add(new Segment3d(P2, P6));
_list_e.Add(new Segment3d(P3, P7));
_list_e.Add(new Segment3d(P4, P8));
return _list_e;
}
else
{
return _list_e;
}
}
}
}
/// <summary>
/// Volume of the box.
/// </summary>
public double Volume
{
get { return _lx * _ly * _lz; }
}
/// <summary>
/// Surface area of the box.
/// </summary>
public double Area
{
get { return 2.0 * (_lx*_ly + _lx*_lz + _ly*_lz); }
}
/// <summary>
/// Length of the box diagonal.
/// </summary>
public double Diagonal
{
get { return Sqrt(_lx * _lx + _ly * _ly + _lz * _lz); }
}
/// <summary>
/// True if box is axis aligned
/// </summary>
public bool IsAxisAligned
{
get { return _r.ToRotationMatrix.IsIdentity; }
}
#endregion
#region "BoundingBox"
/// <summary>
/// Return minimum bounding box.
/// </summary>
public Box3d MinimumBoundingBox
{
get { return this.Copy(); }
}
/// <summary>
/// Return Axis Aligned Bounding Box (AABB).
/// </summary>
public AABB AABB
{
get { return GeometRi.AABB.BoundingBox(this.ListOfPoints); }
}
/// <summary>
/// Return Bounding Box in given coordinate system.
/// </summary>
public Box3d BoundingBox(Coord3d coord = null)
{
coord = (coord == null) ? Coord3d.GlobalCS : coord;
Point3d c = _center.ConvertTo(coord);
double mx = c.X;
double my = c.Y;
double mz = c.Z;
foreach (Point3d p in this.ListOfPoints)
{
Point3d t = p.ConvertTo(coord);
if (t.X < mx) mx = t.X;
if (t.Y < my) my = t.Y;
if (t.Z < mz) mz = t.Z;
}
return new Box3d(c, 2.0 * (c.X - mx), 2.0 * (c.Y - my), 2.0 * (c.Z - mz), coord);
}
/// <summary>
/// Return bounding sphere.
/// </summary>
public Sphere BoundingSphere
{
get
{
double r = 0.5 * Sqrt(_lx * _lx + _ly * _ly + _lz * _lz);
return new Sphere(this.Center, r);
}
}
#endregion
/// <summary>
/// Return Bounding Box for a cloud of points.
/// </summary>
public static Box3d BoundingBox(IEnumerable<Point3d> points, Coord3d coord = null)
{
coord = (coord == null) ? Coord3d.GlobalCS : coord;
double maxx = double.NegativeInfinity;
double maxy = double.NegativeInfinity;
double maxz = double.NegativeInfinity;
double minx = double.PositiveInfinity;
double miny = double.PositiveInfinity;
double minz = double.PositiveInfinity;
foreach (Point3d p in points)
{
Point3d t = p.ConvertTo(coord);
if (t.X > maxx) { maxx = t.X; }
if (t.Y > maxy) { maxy = t.Y; }
if (t.Z > maxz) { maxz = t.Z; }
if (t.X < minx) { minx = t.X; }
if (t.Y < miny) { miny = t.Y; }
if (t.Z < minz) { minz = t.Z; }
}
return new Box3d(new Point3d(0.5*(maxx + minx), 0.5 * (maxy + miny), 0.5 * (maxz + minz)), maxx - minx, maxy - miny, maxz - minz, coord);
}
#region "Intersection"
/// <summary>
/// Get intersection of line with box.
/// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Line3d l)
{
return _line_intersection(l, double.NegativeInfinity, double.PositiveInfinity);
}
/// <summary>
/// Get intersection of ray with box.
/// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Ray3d r)
{
return _line_intersection(r.ToLine, 0.0, double.PositiveInfinity);
}
/// <summary>
/// Get intersection of segment with box.
/// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Segment3d s)
{
return _line_intersection(s.Line, 0.0, s.Length);
}
/// <summary>
/// Check intersection of box with triangle
/// </summary>
public bool Intersects(Triangle t)
{
if (t.A.BelongsTo(this) || t.B.BelongsTo(this) || t.C.BelongsTo(this))
{
return true;
}
foreach (Triangle bt in this.ListOfTriangles)
{
if (bt.Intersects(t)) return true;
}
return false;
}
/// <summary>
/// Check intersection of two boxes (only for AABB boxes, no check is performed for speed)
/// </summary>
public bool Intersects(Box3d box)
{
bool x = Abs(this.Center.X - box.Center.X) <= 0.5 * (this.L1 + box.L1) ? true : false;
bool y = Abs(this.Center.Y - box.Center.Y) <= 0.5 * (this.L2 + box.L2) ? true : false;
bool z = Abs(this.Center.Z - box.Center.Z) <= 0.5 * (this.L3 + box.L3) ? true : false;
return x && y && z;
}
private object _line_intersection(Line3d l, double t0, double t1)
{
// Smith's algorithm:
// "An Efficient and Robust Ray–Box Intersection Algorithm"
// Amy Williams, Steve Barrus, R. Keith Morley, Peter Shirley
// https://people.csail.mit.edu/amy/papers/box-jgt.pdf
// Modified to allow tolerance based checks
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.Diagonal;
GeometRi3D.UseAbsoluteTolerance = true;
object result = _line_intersection(l, t0, t1);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
// Define local CS aligned with box
Coord3d local_CS = this.LocalCoord();
Point3d Pmin = this.P1.ConvertTo(local_CS);
Point3d Pmax = this.P7.ConvertTo(local_CS);
l = new Line3d(l.Point.ConvertTo(local_CS), l.Direction.ConvertTo(local_CS).Normalized);
double tmin, tmax, tymin, tymax, tzmin, tzmax;
double divx = 1 / l.Direction.X;
if (divx >= 0)
{
tmin = (Pmin.X - l.Point.X) * divx;
tmax = (Pmax.X - l.Point.X) * divx;
}
else
{
tmin = (Pmax.X - l.Point.X) * divx;
tmax = (Pmin.X - l.Point.X) * divx;
}
double divy = 1 / l.Direction.Y;
if (divy >= 0)
{
tymin = (Pmin.Y - l.Point.Y) * divy;
tymax = (Pmax.Y - l.Point.Y) * divy;
}
else
{
tymin = (Pmax.Y - l.Point.Y) * divy;
tymax = (Pmin.Y - l.Point.Y) * divy;
}
if (GeometRi3D.Greater(tmin, tymax) || GeometRi3D.Greater(tymin, tmax))
return null;
if (GeometRi3D.Greater(tymin, tmin))
tmin = tymin;
if (GeometRi3D.Smaller(tymax, tmax))
tmax = tymax;
double divz = 1 / l.Direction.Z;
if (divz >= 0)
{
tzmin = (Pmin.Z - l.Point.Z) * divz;
tzmax = (Pmax.Z - l.Point.Z) * divz;
}
else
{
tzmin = (Pmax.Z - l.Point.Z) * divz;
tzmax = (Pmin.Z - l.Point.Z) * divz;
}
if (GeometRi3D.Greater(tmin, tzmax) || GeometRi3D.Greater(tzmin, tmax))
return null;
if (GeometRi3D.Greater(tzmin, tmin))
tmin = tzmin;
if (GeometRi3D.Smaller(tzmax, tmax))
tmax = tzmax;
// Now check the overlapping portion of the segments
// This part is missing in the original algorithm
if (GeometRi3D.Greater(tmin, t1))
return null;
if (GeometRi3D.Smaller(tmax, t0))
return null;
if (GeometRi3D.Smaller(tmin, t0))
tmin = t0;
if (GeometRi3D.Greater(tmax, t1))
tmax = t1;
if (GeometRi3D.AlmostEqual(tmin, tmax))
{
return l.Point.Translate(tmin * l.Direction);
}
else
{
return new Segment3d(l.Point.Translate(tmin * l.Direction), l.Point.Translate(tmax * l.Direction));
}
}
#endregion
/// <summary>
/// Local coordinate system with origin in box's center and aligned with box
/// </summary>
public Coord3d LocalCoord()
{
return _local_coord;
}
/// <summary>
/// Point on box (including interior points) closest to target point "p".
/// </summary>
public Point3d ClosestPoint(Point3d p)
{
Coord3d local_coord = this.LocalCoord();
p = p.ConvertTo(local_coord);
double x = GeometRi3D.Clamp(p.X, -_lx / 2, _lx / 2);
double y = GeometRi3D.Clamp(p.Y, -_ly / 2, _ly / 2);
double z = GeometRi3D.Clamp(p.Z, -_lz / 2, _lz / 2);
return new Point3d(x, y, z, local_coord);
}
/// <summary>
/// Point on axis aligned box (including interior points) closest to target point "p".
/// </summary>
public Point3d AABBClosestPoint(Point3d p)
{
p = p.ConvertToGlobal();
double x = GeometRi3D.Clamp(p.X, this._center.X - _lx / 2, this._center.X + _lx / 2);
double y = GeometRi3D.Clamp(p.Y, this._center.Y - _ly / 2, this._center.Y + _ly / 2);
double z = GeometRi3D.Clamp(p.Z, this._center.Z - _lz / 2, this._center.Z + _lz / 2);
return new Point3d(x, y, z);
}
/// <summary>
/// Distance from box to point (zero will be returned for point located inside box)
/// </summary>
public double DistanceTo(Point3d p)
{
return ClosestPoint(p).DistanceTo(p);
}
/// <summary>
/// Distance from axis aligned box to point (zero will be returned for point located inside box)
/// </summary>
public double AABBDistanceTo(Point3d p)
{
return AABBClosestPoint(p).DistanceTo(p);
}
/// <summary>
/// Shortest distance from box to sphere
/// </summary>
public double DistanceTo(Sphere s)
{
Point3d p = this.ClosestPoint(s._point);
double dist = p.DistanceTo(s._point);
return dist <= s.R ? 0.0 : dist - s.R;
}
/// <summary>
/// Shortest distance from box to circle
/// </summary>
public double DistanceTo(Circle3d c)
{
if (c._point.IsInside(this))
{
return 0;
}
double min_dist = Double.PositiveInfinity;
foreach (Triangle triangle in ListOfTriangles)
{
double dist = c.DistanceTo(triangle);
if (dist <= GeometRi3D.Tolerance) return 0;
if (dist < min_dist) min_dist = dist;
}
return min_dist;
}
/// <summary>
/// Intersection check between circle and box
/// </summary>
public bool Intersects(Circle3d c)
{
//if (c.Center.IsInside(this)) return true;
double dist = c._point.DistanceTo(this);
if (dist > c.R) return false;
if (dist < GeometRi3D.Tolerance) return true;
foreach (Triangle triangle in ListOfTriangles)
{
if (c.Intersects(triangle)) return true;
}
return false;
}
internal override int _PointLocation(Point3d p)
{
Coord3d coord = this.LocalCoord();
p = p.ConvertTo(coord);
if (GeometRi3D.UseAbsoluteTolerance)
{
if ( (Abs(p.X)-L1/2) <= GeometRi3D.Tolerance && (Abs(p.Y) - L2 / 2) <= GeometRi3D.Tolerance && (Abs(p.Z) - L3 / 2) <= GeometRi3D.Tolerance )
{
if ( (Abs(p.X) - L1 / 2) < -GeometRi3D.Tolerance && (Abs(p.Y) - L2 / 2) < -GeometRi3D.Tolerance && (Abs(p.Z) - L3 / 2) < -GeometRi3D.Tolerance)
{
return 1; // Point is strictly inside box
} else
{
return 0; // Point is on boundary
}
} else
{
return -1; // Point is outside
}
}
else
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.Diagonal;
GeometRi3D.UseAbsoluteTolerance = true;
int result = this._PointLocation(p);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
}
#region "TranslateRotateReflect"
/// <summary>
/// Translate box by a vector
/// </summary>
public Box3d Translate(Vector3d v)
{
return new Box3d(_center.Translate(v), _lx, _ly, _lz);
}
/// <summary>
/// Rotate box around point 'p' as a rotation center.
/// </summary>
public Box3d Rotate(Rotation r, Point3d p)
{
Point3d new_center = r.ToRotationMatrix * (this._center - p) + p;
Rotation new_rotation = r * this.Orientation;
return new Box3d(new_center, _lx, _ly, _lz, new_rotation);
}
/// <summary>
/// Reflect box in given point
/// <para>The order of corner points will be changed during reflection operation.</para>
/// </summary>
public virtual Box3d ReflectIn(Point3d p)
{
Point3d new_center = this.Center.ReflectIn(p);
return new Box3d(new_center, _lx, _ly, _lz, this._r);
}
/// <summary>
/// Reflect box in given line
/// <para>The order of corner points will be changed during reflection operation.</para>
/// </summary>
public virtual Box3d ReflectIn(Line3d l)
{
Point3d new_center = this.Center.ReflectIn(l);
Rotation r = new GeometRi.Rotation(l.Direction, PI);
Rotation new_rotation = r * this.Orientation;
return new Box3d(new_center, _lx, _ly, _lz, new_rotation);
}
/// <summary>
/// Reflect box in given plane
/// <para>The order of corner points will be changed during reflection operation.</para>
/// </summary>
public virtual Box3d ReflectIn(Plane3d s)
{
Point3d new_center = this.Center.ReflectIn(s);
Vector3d nV1 = this.V1.ReflectIn(s);
Vector3d nV2 = this.V2.ReflectIn(s);
Coord3d coord = new Coord3d(new_center, nV1, nV2);
Rotation new_rotation = new Rotation(coord);
return new Box3d(new_center, _lx, _ly, _lz, new_rotation);
}
/// <summary>
/// Scale box relative to given point
/// </summary>
public virtual Box3d Scale(double scale, Point3d scaling_center)
{
Point3d new_center = scaling_center + scale * (this.Center - scaling_center);
return new Box3d(new_center, scale * _lx, scale * _ly, scale * _lz, this._r);
}
#endregion
/// <summary>
/// Determines whether two objects are equal.
/// </summary>
public override bool Equals(object obj)
{
if (obj == null || (!object.ReferenceEquals(this.GetType(), obj.GetType())))
{
return false;
}
Box3d b = (Box3d)obj;
if (GeometRi3D.UseAbsoluteTolerance)
{
return this.Center == b.Center && _r == b.Orientation &&
GeometRi3D.AlmostEqual(L1, b.L1) &&
GeometRi3D.AlmostEqual(L2, b.L2) &&
GeometRi3D.AlmostEqual(L3, b.L3);
}
else
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.Diagonal;
GeometRi3D.UseAbsoluteTolerance = true;
bool result = this.Equals(b);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
}
/// <summary>
/// Returns the hashcode for the object.
/// </summary>
public override int GetHashCode()
{
int hash_code = GeometRi3D.HashFunction(_lx.GetHashCode(), _ly.GetHashCode(), _lz.GetHashCode());
return GeometRi3D.HashFunction(_center.GetHashCode(), _r.GetHashCode(), hash_code);
}
/// <summary>
/// String representation of an object in global coordinate system.
/// </summary>
public override string ToString()
{
return ToString(Coord3d.GlobalCS);
}
/// <summary>
/// String representation of an object in reference coordinate system.
/// </summary>
public string ToString(Coord3d coord)
{
string nl = System.Environment.NewLine;
if (coord == null) { coord = Coord3d.GlobalCS; }
Point3d p = _center.ConvertTo(coord);
string str = string.Format("Box3d (reference coord.sys. ") + coord.Name + "):" + nl;
str += string.Format("Center -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", p.X, p.Y, p.Z) + nl;
str += string.Format("Lx, Ly, Lz -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", _lx, _ly, _lz) + nl;
str += _r.ToString(coord);
return str;
}
// Operators overloads
//-----------------------------------------------------------------
public static bool operator ==(Box3d b1, Box3d b2)
{
if (object.ReferenceEquals(b1, null))
return object.ReferenceEquals(b2, null);
return b1.Equals(b2);
}
public static bool operator !=(Box3d b1, Box3d b2)
{
if (object.ReferenceEquals(b1, null))
return !object.ReferenceEquals(b2, null);
return !b1.Equals(b2);
}
}
}
================================================
FILE: GeometRi/Circle3D.cs
================================================
using System;
using System.Collections.Generic;
using System.Drawing;
using static System.Math;
namespace GeometRi
{
/// <summary>
/// Circle in 3D space defined by center point, radius and normal vector.
/// </summary>
#if NET20_OR_GREATER
[Serializable]
#endif
public class Circle3d : FiniteObject, IPlanarObject, IFiniteObject
{
internal Point3d _point;
private double _r;
internal Vector3d _normal;
/// <summary>
/// Initializes circle instance using center point, radius and normal vector.
/// </summary>
public Circle3d(Point3d Center, double Radius, Vector3d Normal)
{
_point = Center.Copy();
_r = Radius;
_normal = Normal.Normalized;
}
/// <summary>
/// Initializes circle passing through three points.
/// </summary>
public Circle3d(Point3d p1, Point3d p2, Point3d p3)
{
Vector3d v1 = new Vector3d(p1, p2);
Vector3d v2 = new Vector3d(p1, p3);
if (v1.Cross(v2).Norm < GeometRi3D.Tolerance)
{
throw new Exception("Collinear points");
}
Coord3d CS = new Coord3d(p1, v1, v2);
Point3d a1 = p1.ConvertTo(CS);
Point3d a2 = p2.ConvertTo(CS);
Point3d a3 = p3.ConvertTo(CS);
double d1 = Math.Pow(a1.X, 2) + Math.Pow(a1.Y, 2);
double d2 = Math.Pow(a2.X, 2) + Math.Pow(a2.Y, 2);
double d3 = Math.Pow(a3.X, 2) + Math.Pow(a3.Y, 2);
double f = 2.0 * (a1.X * (a2.Y - a3.Y) - a1.Y * (a2.X - a3.X) + a2.X * a3.Y - a3.X * a2.Y);
double X = (d1 * (a2.Y - a3.Y) + d2 * (a3.Y - a1.Y) + d3 * (a1.Y - a2.Y)) / f;
double Y = (d1 * (a3.X - a2.X) + d2 * (a1.X - a3.X) + d3 * (a2.X - a1.X)) / f;
//_point = (new Point3d(X, Y, 0, CS)).ConvertTo(p1.Coord);
_point = new Point3d(X, Y, 0, CS);
_point = _point.ConvertTo(p1.Coord);
_r = Sqrt((X - a1.X) * (X - a1.X) + (Y - a1.Y) * (Y - a1.Y));
_normal = v1.Cross(v2).Normalized;
}
/// <summary>
/// Creates copy of the object
/// </summary>
public Circle3d Copy()
{
return new Circle3d(_point, _r, _normal);
}
/// <summary>
/// Center of the circle
/// </summary>
public Point3d Center
{
get { return _point; }
set { _point = value.Copy(); }
}
/// <summary>
/// X component of the circles' center
/// </summary>
public double X
{
get { return _point.X; }
//set { _point.X = value; }
}
/// <summary>
/// Y component of the circles' center
/// </summary>
public double Y
{
get { return _point.Y; }
//set { _point.Y = value; }
}
/// <summary>
/// Z component of the circles' center
/// </summary>
public double Z
{
get { return _point.Z; }
//set { _point.Z = value; }
}
/// <summary>
/// Radius of the circle
/// </summary>
public double R
{
get { return _r; }
set { _r = value; }
}
/// <summary>
/// Normal of the circle
/// </summary>
public Vector3d Normal
{
get { return _normal; }
set { _normal = value.Copy(); }
}
public bool IsOriented
{
get { return false; }
}
public double Perimeter
{
get { return 2 * PI * _r; }
}
/// <summary>
/// Area of the circle.
/// </summary>
public double Area
{
get { return PI * _r * _r; }
}
/// <summary>
/// Convert circle to ellipse object.
/// </summary>
public Ellipse ToEllipse
{
get
{
Vector3d v1 = _r * _normal.OrthogonalVector.Normalized;
Vector3d v2 = _r * (_normal.Cross(v1)).Normalized;
return new Ellipse(_point, v1, v2);
}
}
/// <summary>
/// Convert circle to plane object.
/// </summary>
public Plane3d ToPlane
{
get
{
return new Plane3d(_point, _normal);
}
}
#region "ParallelMethods"
/// <summary>
/// Check if two objects are parallel
/// </summary>
public bool IsParallelTo(ILinearObject obj)
{
return this.Normal.IsOrthogonalTo(obj.Direction);
}
/// <summary>
/// Check if two objects are NOT parallel
/// </summary>
public bool IsNotParallelTo(ILinearObject obj)
{
return !this.Normal.IsOrthogonalTo(obj.Direction);
}
/// <summary>
/// Check if two objects are orthogonal
/// </summary>
public bool IsOrthogonalTo(ILinearObject obj)
{
return this.Normal.IsParallelTo(obj.Direction);
}
/// <summary>
/// Check if two objects are parallel
/// </summary>
public bool IsParallelTo(IPlanarObject obj)
{
return this.Normal.IsParallelTo(obj.Normal);
}
/// <summary>
/// Check if two objects are NOT parallel
/// </summary>
public bool IsNotParallelTo(IPlanarObject obj)
{
return this.Normal.IsNotParallelTo(obj.Normal);
}
/// <summary>
/// Check if two objects are orthogonal
/// </summary>
public bool IsOrthogonalTo(IPlanarObject obj)
{
return this.Normal.IsOrthogonalTo(obj.Normal);
}
/// <summary>
/// Check if two objects are coplanar
/// </summary>
public bool IsCoplanarTo(IPlanarObject obj)
{
return GeometRi3D._coplanar(this, obj);
}
/// <summary>
/// Check if two objects are coplanar
/// </summary>
public bool IsCoplanarTo(ILinearObject obj)
{
return GeometRi3D._coplanar(this, obj);
}
#endregion
#region "BoundingBox"
/// <summary>
/// Return minimum bounding box.
/// </summary>
public Box3d MinimumBoundingBox
{
get
{
Vector3d v1 = this.Normal.OrthogonalVector.Normalized;
Vector3d v2 = this.Normal.Cross(v1).Normalized;
Vector3d v3 = this.Normal;
Matrix3d m = new Matrix3d(v1, v2, v3);
Rotation r = new Rotation(m.Transpose());
return new Box3d(_point, 2.0 * _r, 2.0 * _r, 0, r);
}
}
/// <summary>
/// Return Bounding Box in given coordinate system.
/// </summary>
public Box3d BoundingBox(Coord3d coord = null)
{
coord = (coord == null) ? Coord3d.GlobalCS : coord;
Vector3d v = _normal.ConvertTo(coord);
double s1 = _r * Sqrt(1 - v.X * v.X);
double s2 = _r * Sqrt(1 - v.Y * v.Y);
double s3 = _r * Sqrt(1 - v.Z * v.Z);
return new Box3d(_point, 2 * s1, 2 * s2, 2 * s3, coord);
}
/// <summary>
/// Return Axis Aligned Bounding Box (AABB).
/// </summary>
public AABB AABB()
{
Vector3d v = _normal.ConvertToGlobal();
double s1 = _r * Sqrt(1 - v.X * v.X);
double s2 = _r * Sqrt(1 - v.Y * v.Y);
double s3 = _r * Sqrt(1 - v.Z * v.Z);
return new AABB(_point, 2 * s1, 2 * s2, 2 * s3);
}
/// <summary>
/// Return bounding sphere.
/// </summary>
public Sphere BoundingSphere
{
get { return new Sphere(_point, _r); }
}
/// <summary>
/// Check if circle is located inside box with tolerance defined by global tolerance property (GeometRi3D.Tolerance).
/// </summary>
public bool IsInside(Box3d box)
{
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.R;
GeometRi3D.UseAbsoluteTolerance = true;
bool result = this.IsInside(box);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
if (!this._point.IsInside(box)) return false;
Coord3d local_coord = box.LocalCoord();
Box3d circle_box = this.BoundingBox(local_coord);
Point3d p = _point.ConvertTo(local_coord);
if (box.L1 / 2 - (Abs(p.X) + circle_box.L1 / 2) < GeometRi3D.Tolerance) return false;
if (box.L2 / 2 - (Abs(p.Y) + circle_box.L2 / 2) < GeometRi3D.Tolerance) return false;
if (box.L3 / 2 - (Abs(p.Z) + circle_box.L3 / 2) < GeometRi3D.Tolerance) return false;
return true;
}
#endregion
/// <summary>
/// Returns point on circle for given parameter 't' (0 <= t < 2Pi)
/// </summary>
public Point3d ParametricForm(double t)
{
// Get two orthogonal coplanar vectors
Vector3d v1 = _r * _normal.OrthogonalVector.Normalized;
Vector3d v2 = _r * (_normal.Cross(v1)).Normalized;
return _point + v1 * Cos(t) + v2 * Sin(t);
}
#region "DistanceMethods"
/// <summary>
/// Distance from circle to plane
/// </summary>
public double DistanceTo(Plane3d s)
{
double center_distance = Math.Abs((this._point - s._point).Dot(s._normal));
double sin_angle = this._normal.Cross(s._normal).Norm;
double delta = Abs(this.R * sin_angle);
if (delta < center_distance)
{
return center_distance - delta;
}
else
{
return 0;
}
}
/// <summary>
/// Shortest distance between plane and circle
/// <para> The output points may be not unique in case of parallel or intersecting objects.</para>
/// </summary>
/// <param name="p">Target plane</param>
/// <param name="point_on_circle">Closest point on circle</param>
/// <param name="point_on_plane">Closest point on plane</param>
public double DistanceTo(Plane3d p, out Point3d point_on_circle, out Point3d point_on_plane)
{
if (this.IsParallelTo(p))
{
point_on_circle = this.Center;
point_on_plane = point_on_circle.ProjectionTo(p);
return point_on_circle.DistanceTo(point_on_plane);
}
Vector3d v1 = this._normal.Cross(p.Normal);
Vector3d v2 = this._normal.Cross(v1);
double d = (p._point - this._point).Dot(p._normal) / (p._normal * v2);
Point3d intersection_point = this._point.Translate(d * v2);
if (intersection_point.DistanceTo(this.Center) <= this.R)
{
point_on_circle = intersection_point;
point_on_plane = intersection_point;
return 0;
}
else
{
point_on_circle = this._point.Translate(Sign(d) * this.R * v2.Normalized);
point_on_plane = point_on_circle.ProjectionTo(p);
return point_on_circle.DistanceTo(point_on_plane);
//Point3d delta = point_on_circle - p._point;
//double dist = delta.Dot(p._normal);
//point_on_plane = point_on_circle - dist * p._normal;
//return dist;
}
}
/// <summary>
/// Shortest distance from point to circle (including interior points)
/// </summary>
public double DistanceTo(Point3d p)
{
Point3d delta = p - this._point;
Point3d Q = p.Subtract(this._normal, delta.Dot(this._normal));
double dist = this._point.DistanceTo(Q);
if (dist < this._r)
{
return Q.DistanceTo(p); ;
}
else
{
Point3d K = this._point + this._r / dist * (Q - this._point);
return K.DistanceTo(p); ;
}
}
/// <summary>
/// Point on circle (including interior points) closest to target point "p".
/// </summary>
public Point3d ClosestPoint(Point3d p)
{
Point3d delta = p - this._point;
Point3d Q = p.Subtract(this._normal, delta.Dot(this._normal));
double dist = this._point.DistanceTo(Q);
if (dist < this._r)
{
return Q;
}
else
{
return this._point + this._r / dist * (Q - this._point);
}
}
/// <summary>
/// Point on circle (excluding interior points) closest to target point "p".
/// </summary>
public Point3d ClosestPointOnBoundary(Point3d p)
{
Point3d delta = p - this._point;
Point3d Q = p.Subtract(this._normal, delta.Dot(this._normal));
double dist = this._point.DistanceTo(Q);
return this._point + this._r / dist * (Q - this._point);
}
/// <summary>
/// Shortest distance between two circles (including interior points) (approximate solution)
/// <para> Default tolerance for numerical solution: GeometRi3D.DefaultTolerance.</para>
/// </summary>
/// <param name="c">Target circle</param>
public double DistanceTo(Circle3d c)
{
return DistanceTo(c, GeometRi3D.DefaultTolerance);
}
/// <summary>
/// Shortest distance between two circles (including interior points) (approximate solution)
/// </summary>
/// <param name="c">Target circle</param>
/// <param name="tolerance">Tolerance for numerical solution, default GeometRi3D.DefaultTolerance</param>
public double DistanceTo(Circle3d c, double tolerance)
{
double dist;
if (GeometRi3D.AlmostEqual(Abs(this._normal * c._normal), 1.0))
{
Point3d projection = c._point.ProjectionTo(this.ToPlane);
dist = projection.DistanceTo(this._point);
double vdist = projection.DistanceTo(c._point);
if (dist < this.R + c.R)
{
return vdist;
}
else
{
return Sqrt((dist - this.R - c.R) * (dist - this.R - c.R) + vdist * vdist);
}
}
double tol = GeometRi3D.Tolerance;
bool mode = GeometRi3D.UseAbsoluteTolerance;
GeometRi3D.Tolerance = GeometRi3D.DefaultTolerance;
GeometRi3D.UseAbsoluteTolerance = true;
//object obj = this.IntersectionWith(c);
if (_circle_circle_intersection_check_2(c))
{
// Restore initial state
GeometRi3D.UseAbsoluteTolerance = mode;
GeometRi3D.Tolerance = tol;
return 0;
}
Point3d p_on_circle, p_on_plane;
dist = this.DistanceTo(c.ToPlane, out p_on_circle, out p_on_plane);
if (p_on_plane.DistanceTo(c._point) <= c.R)
{
// Restore initial state
GeometRi3D.UseAbsoluteTolerance = mode;
GeometRi3D.Tolerance = tol;
return dist;
}
dist = c.DistanceTo(this.ToPlane, out p_on_circle, out p_on_plane);
if (p_on_plane.DistanceTo(this._point) <= this.R)
{
// Restore initial state
GeometRi3D.UseAbsoluteTolerance = mode;
GeometRi3D.Tolerance = tol;
return dist;
}
dist = _distance_circle_to_circle(this, c, out Point3d p1, out Point3d p2, tolerance);
// Restore initial state
GeometRi3D.UseAbsoluteTolerance = mode;
GeometRi3D.Tolerance = tol;
return dist;
}
/// <summary>
/// Shortest distance between two circles (including interior points) (approximate solution)
/// <para> The output points may be not unique in case of parallel or intersecting circles.</para>
/// <para> Default tolerance for numerical solution: GeometRi3D.DefaultTolerance.</para>
/// </summary>
/// <param name="c">Target circle</param>
/// <param name="p1">Closest point on source circle</param>
/// <param name="p2">Closest point on target circle</param>
public double DistanceTo(Circle3d c, out Point3d p1, out Point3d p2)
{
return DistanceTo(c, out p1, out p2, GeometRi3D.DefaultTolerance);
}
/// <summary>
/// Shortest distance between two circles (including interior points) (approximate solution)
/// <para> The output points may be not unique in case of parallel or intersecting circles.</para>
/// </summary>
/// <param name="c">Target circle</param>
/// <param name="p1">Closest point on source circle</param>
/// <param name="p2">Closest point on target circle</param>
/// <param name="tolerance">Tolerance for numerical solution, default GeometRi3D.DefaultTolerance</param>
public double DistanceTo(Circle3d c, out Point3d p1, out Point3d p2, double tolerance)
{
double dist;
if (GeometRi3D.AlmostEqual(Abs(this._normal * c._normal), 1.0))
{
Point3d projection = c._point.ProjectionTo(this.ToPlane);
dist = projection.DistanceTo(this._point);
double vdist = projection.DistanceTo(c._point);
if (dist < this.R + c.R)
{
if (projection.BelongsTo(this))
{
p1 = projection;
p2 = c.Center;
}
else
{
p1 = this._point.Translate(this.R * new Vector3d(this._point, projection).Normalized);
p2 = p1.ProjectionTo(c.ToPlane);
}
return vdist;
}
else
{
Vector3d v = new Vector3d(this._point, projection).Normalized;
p1 = this._point.Translate(this.R * v);
p2 = c._point.Translate(-c.R * v);
return Sqrt((dist - this.R - c.R) * (dist - this.R - c.R) + vdist * vdist);
}
}
double tol = GeometRi3D.Tolerance;
bool mode = GeometRi3D.UseAbsoluteTolerance;
GeometRi3D.Tolerance = GeometRi3D.DefaultTolerance;
GeometRi3D.UseAbsoluteTolerance = true;
object obj = this.IntersectionWith(c);
if (obj != null)
{
// Restore initial state
GeometRi3D.UseAbsoluteTolerance = mode;
GeometRi3D.Tolerance = tol;
if (obj.GetType() == typeof(Point3d))
{
p1 = (Point3d)obj;
p2 = (Point3d)obj;
}
else if (obj.GetType() == typeof(Segment3d))
{
p1 = ((Segment3d)obj).P1;
p2 = ((Segment3d)obj).P1;
}
else
{
p1 = ((Circle3d)obj).Center;
p2 = ((Circle3d)obj).Center;
}
return 0;
}
dist = this.DistanceTo(c.ToPlane, out p1, out p2);
if (p2.DistanceTo(c._point) <= c.R)
{
// Restore initial state
GeometRi3D.UseAbsoluteTolerance = mode;
GeometRi3D.Tolerance = tol;
return dist;
}
dist = c.DistanceTo(this.ToPlane, out p2, out p1);
if (p1.DistanceTo(this._point) <= this.R)
{
// Restore initial state
GeometRi3D.UseAbsoluteTolerance = mode;
GeometRi3D.Tolerance = tol;
return dist;
}
dist = _distance_circle_to_circle(this, c, out p1, out p2, tolerance);
// Restore initial state
GeometRi3D.UseAbsoluteTolerance = mode;
GeometRi3D.Tolerance = tol;
return dist;
}
/// <summary>
/// Check if distance between two circles is greater than threshold
/// </summary>
public bool DistanceGreater(Circle3d c, double threshold, double tolerance)
{
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * Max(this.R, c.R);
GeometRi3D.UseAbsoluteTolerance = true;
bool result = this.DistanceGreater(c, threshold, tolerance);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
// Early exit (separated circles)
double d = this._point.DistanceTo(c._point);
if (d > this.R + c.R + GeometRi3D.Tolerance + threshold)
return true;
if (GeometRi3D.AlmostEqual(Abs(this._normal * c._normal), 1.0))
{
if (this._point.BelongsTo(new Plane3d(c._point, c._normal)))
{
// Coplanar objects
if (d <= this.R + c.R + GeometRi3D.Tolerance + threshold)
{
return false;
}
else
{
return true;
}
}
else
{
// parallel objects
return this.DistanceTo(c, out Point3d p1, out Point3d p2, tolerance) > threshold;
}
}
else
{
// Check 3D intersection
//Vector3d v = new Vector3d(this._point, c._point);
Point3d v = c._point - this._point;
//double this_norm = this._normal.Norm;
//double c_norm = c._normal.Norm;
double this_norm = 1;
double c_norm = 1;
double cos_angle1 = v.Dot(this._normal) / this_norm / d;
double delta1 = Abs(d * cos_angle1);
double sin_angle2 = this._normal.Cross(c._normal).Norm / this_norm / c_norm;
double delta2 = Abs(this.R * sin_angle2);
if (delta1 > delta2 + threshold) return true;
cos_angle1 = v.Dot(c._normal) / c_norm / d;
delta1 = Abs(d * cos_angle1);
delta2 = Abs(c.R * sin_angle2);
if (delta1 > delta2 + threshold) return true;
return this.DistanceTo(c, tolerance) > threshold;
}
}
private double _distance_circle_to_circle_new(Circle3d c1, Circle3d c2, out Point3d p1, out Point3d p2, double tol)
{
double dist_prev = double.PositiveInfinity;
int max_iter = 100;
p1 = c1.ClosestPointOnBoundary(c2.Center);
p2 = c2.ClosestPointOnBoundary(p1);
double dist = p1.DistanceTo(p2);
int iter = 0;
while (iter < max_iter)
{
dist_prev = dist;
p1 = c1.ClosestPointOnBoundary(p2);
p2 = c2.ClosestPointOnBoundary(p1);
dist = p1.DistanceTo(p2);
if (Math.Abs(dist - dist_prev) < tol)
{
return dist;
}
iter++;
}
return dist;
}
private double _distance_circle_to_circle(Circle3d c1, Circle3d c2, out Point3d p1, out Point3d p2, double tol)
// Use quadratic interpolation to find closest point on one circle to other
// p1 and p2 - closest points on both circles
{
//double tol = GeometRi3D.DefaultTolerance;
double d1 = 1e20;
double t1 = 0;
Point3d p;
// Prepare data for parametric form for circle "c1".
// _point + v1.ToPoint * Cos(t) + v2.ToPoint * Sin(t);
// Get two orthogonal vectors coplanar "c1"
Vector3d v1 = c1._r * c1._normal.OrthogonalVector.Normalized;
Vector3d v2 = c1._r * (c1._normal.Cross(v1)).Normalized;
Point3d pf1 = v1.ToPoint.ConvertTo(c1._point.Coord);
Point3d pf2 = v2.ToPoint.ConvertTo(c1._point.Coord);
for (int i = 0; i < 16; i++)
{
double t = i * Math.PI / 8;
p = c1._point + pf1 * Cos(t) + pf2 * Sin(t);
double dist = p.DistanceTo(c2);
if (dist < d1)
{
d1 = dist;
t1 = t;
}
}
double t2 = t1 - Math.PI / 8;
p = c1._point + pf1 * Cos(t2) + pf2 * Sin(t2);
double d2 = p.DistanceTo(c2);
double t3 = t1 + Math.PI / 8;
p = c1._point + pf1 * Cos(t3) + pf2 * Sin(t3);
double d3 = p.DistanceTo(c2);
int iter = 0;
bool flag = false;
while ((d2 - d1 > tol || d3 - d1 > tol) && d1 > tol)
{
if (++iter > 100) break;
double ax = 2.0 * d1 / (t1 - t2) / (t1 - t3);
double aa = 0.5 * ax * (t2 + t3);
double bx = 2.0 * d2 / (t2 - t1) / (t2 - t3);
double bb = 0.5 * bx * (t1 + t3);
double cx = 2.0 * d3 / (t3 - t1) / (t3 - t2);
double cc = 0.5 * cx * (t1 + t2);
double t = (aa + bb + cc) / (ax + bx + cx);
p = c1._point + pf1 * Cos(t) + pf2 * Sin(t);
double d = p.DistanceTo(c2);
if (d > d1)
// Possible special case, non-smooth function ( f(t)=|t| )
{
flag = true;
break;
}
if (t>t2 & t<t1)
{
t3 = t1; d3 = d1;
}
else
{
t2 = t1; d2 = d1;
}
t1 = t; d1 = d;
}
if (flag)
// Possible special case, non-smooth function ( f(t)=|t| )
{
while ((d2 - d1 > tol || d3 - d1 > tol) && d1 > tol)
{
if (++iter > 100) break;
double t = (t2+t1) / 2;
p = c1._point + pf1 * Cos(t) + pf2 * Sin(t);
double d = p.DistanceTo(c2);
if (d < d1)
{
t3 = t1; d3 = d1;
t1 = t; d1 = d;
}
else
{
t2 = t; d2 = d;
}
t = (t3 + t1) / 2;
p = c1._point + pf1 * Cos(t) + pf2 * Sin(t);
d = p.DistanceTo(c2);
if (d < d1)
{
t2 = t1; d2 = d1;
t1 = t; d1 = d;
}
else
{
t3 = t; d3 = d;
}
}
}
p1 = c1._point + pf1 * Cos(t1) + pf2 * Sin(t1);
p2 = c2.ClosestPoint(p1);
return d1;
}
/// <summary>
/// Shortest distance between circle and sphere (including interior points) (approximate solution)
/// </summary>
public double DistanceTo(Sphere s)
{
return DistanceTo(s, GeometRi3D.DefaultTolerance);
}
/// <summary>
/// Shortest distance between circle and sphere (including interior points) (approximate solution)
/// </summary>
/// <param name="s">Target sphere</param>
/// <param name="tolerance">Tolerance for numerical solution, default GeometRi3D.DefaultTolerance</param>
public double DistanceTo(Sphere s, double tolerance)
{
Plane3d p = this.ToPlane;
if (s.Center.ProjectionTo(p).BelongsTo(this))
{
return s.DistanceTo(p);
}
if (this.Intersects(s))
return 0;
Point3d p1, p2;
double dist = _distance_circle_to_sphere(this, s, out p1, out p2, tolerance);
return dist;
}
/// <summary>
/// Shortest distance between circle and sphere (including interior points) (approximate solution)
/// <para> The output points may be not unique in case of intersecting objects.</para>
/// <para> Default tolerance for numerical solution: GeometRi3D.DefaultTolerance.</para>
/// </summary>
/// <param name="s">Target sphere</param>
/// <param name="p1">Closest point on circle</param>
/// <param name="p2">Closest point on sphere</param>
public double DistanceTo(Sphere s, out Point3d p1, out Point3d p2)
{
return DistanceTo(s, out p1, out p2, GeometRi3D.DefaultTolerance);
}
/// <summary>
/// Shortest distance between circle and sphere (including interior points) (approximate solution)
/// <para> The output points may be not unique in case of intersecting objects.</para>
/// </summary>
/// <param name="s">Target sphere</param>
/// <param name="p1">Closest point on circle</param>
/// <param name="p2">Closest point on sphere</param>
/// <param name="tolerance">Tolerance for numerical solution, default GeometRi3D.DefaultTolerance</param>
public double DistanceTo(Sphere s, out Point3d p1, out Point3d p2, double tolerance)
{
Plane3d p = this.ToPlane;
if (s.Center.ProjectionTo(p).BelongsTo(this))
{
p1 = s.Center.ProjectionTo(p);
if (s.Center == p1)
{
p2 = s.Center.Translate(s.R * this.Normal);
}
else
{
p2 = s.Center.Translate(s.R * new Vector3d(s.Center, p1).Normalized);
}
return s.DistanceTo(p);
}
if (this.Intersects(s))
{
Object obj = s.IntersectionWith(p);
if (obj.GetType() == typeof(Point3d))
{
p1 = (Point3d)obj;
p2 = p1;
}
else
{
Circle3d c = (Circle3d)obj;
p1 = this._point.Translate(this.R * new Vector3d(this._point, c._point).Normalized);
p2 = c._point.Translate(c.R * new Vector3d(c._point, this._point).Normalized);
}
return 0;
}
double dist = _distance_circle_to_sphere(this, s, out p1, out p2, tolerance);
return dist;
}
private double _distance_circle_to_sphere(Circle3d c1, Sphere c2, out Point3d p1, out Point3d p2, double tol)
// Use quadratic interpolation to find closest point on circle
// p1 and p2 - closest points on circle and sphere respectively
{
double d1 = 1e20;
double t1 = 0;
Point3d p;
for (int i = 0; i < 16; i++)
{
double t = i * Math.PI / 8;
p = c1.ParametricForm(t);
double dist = p.DistanceTo(c2);
if (dist < d1)
{
d1 = dist;
t1 = t;
}
}
double t2 = t1 - Math.PI / 8;
p = c1.ParametricForm(t2);
double d2 = p.DistanceTo(c2);
double t3 = t1 + Math.PI / 8;
p = c1.ParametricForm(t3);
double d3 = p.DistanceTo(c2);
int iter = 0;
while (d2 - d1 > 0.2 * tol && d1 > tol)
{
if (++iter > 100) break;
double ax = 2.0 * d1 / (t1 - t2) / (t1 - t3);
double aa = 0.5 * ax * (t2 + t3);
double bx = 2.0 * d2 / (t2 - t1) / (t2 - t3);
double bb = 0.5 * bx * (t1 + t3);
double cx = 2.0 * d3 / (t3 - t1) / (t3 - t2);
double cc = 0.5 * cx * (t1 + t2);
double t = (aa + bb + cc) / (ax + bx + cx);
p = c1.ParametricForm(t);
double d = p.DistanceTo(c2);
if (d < d1)
{
if (t > t2 & t < t1)
{
t3 = t1; d3 = d1;
}
else
{
t2 = t1; d2 = d1;
}
t1 = t; d1 = d;
}
else
{
if (t < t1)
{
t2 = t; d2 = d;
}
else
{
t3 = t; d3 = d;
}
}
}
p1 = c1.ParametricForm(t1);
p2 = c2.ClosestPoint(p1);
return d1;
}
/// <summary>
/// Shortest distance between line and circle (including interior points)
/// </summary>
public double DistanceTo(Line3d l)
{
Point3d point_on_circle, point_on_line;
double dist = _distance_circle_to_line(l, out point_on_circle, out point_on_line);
return dist;
}
/// <summary>
/// Shortest distance between line and circle (excluding interior points)
/// </summary>
public double DistanceToBoundary(Line3d l)
{
Point3d point_on_circle, point_on_line;
double dist = _distance_circle_boundary_to_line(l, out point_on_circle, out point_on_line);
return dist;
}
/// <summary>
/// Shortest distance between line and circle (including interior points)
/// </summary>
/// <param name="l">Target line</param>
/// <param name="point_on_circle">Closest point on circle</param>
/// <param name="point_on_line">Closest point on line</param>
public double DistanceTo(Line3d l, out Point3d point_on_circle, out Point3d point_on_line)
{
double dist = _distance_circle_to_line(l, out point_on_circle, out point_on_line);
return dist;
}
/// <summary>
/// Shortest distance between line and circle (excluding interior points)
/// </summary>
/// <param name="l">Target line</param>
/// <param name="point_on_circle">Closest point on circle</param>
/// <param name="point_on_line">Closest point on line</param>
public double DistanceToBoundary(Line3d l, out Point3d point_on_circle, out Point3d point_on_line)
{
double dist = _distance_circle_boundary_to_line(l, out point_on_circle, out point_on_line);
return dist;
}
/// <summary>
/// Shortest distance between ray and circle (including interior points)
/// </summary>
public double DistanceTo(Ray3d r)
{
Point3d point_on_circle, point_on_ray;
return DistanceTo(r, out point_on_circle, out point_on_ray);
}
/// <summary>
/// Shortest distance between ray and circle (including interior points)
/// </summary>
/// <param name="r">Target ray</param>
/// <param name="point_on_circle">Closest point on circle</param>
/// <param name="point_on_ray">Closest point on ray</param>
public double DistanceTo(Ray3d r, out Point3d point_on_circle, out Point3d point_on_ray)
{
double dist = _distance_circle_to_line(r.ToLine, out point_on_circle, out point_on_ray);
if (point_on_ray.BelongsTo(r)) return dist;
point_on_ray = r.Point;
point_on_circle = this.ClosestPoint(point_on_ray);
return point_on_ray.DistanceTo(point_on_circle);
}
/// <summary>
/// Shortest distance between segment and circle (including interior points)
/// </summary>
public double DistanceTo(Segment3d s)
{
Point3d point_on_circle, point_on_ray;
return DistanceTo(s, out point_on_circle, out point_on_ray);
}
/// <summary>
/// Shortest distance between segment and circle (including interior points)
/// </summary>
/// <param name="s">Target segment</param>
/// <param name="point_on_circle">Closest point on circle</param>
/// <param name="point_on_segment">Closest point on segment</param>
public double DistanceTo(Segment3d s, out Point3d point_on_circle, out Point3d point_on_segment)
{
Line3d l = s.Line;
Plane3d plane = this.ToPlane;
if (l.IsNotParallelTo(plane._normal))
{
Line3d l_projection = (Line3d)l.ProjectionTo(plane);
Object obj = l_projection.IntersectionWith(this);
if (obj != null && obj.GetType() == typeof(Segment3d))
{
Segment3d segm = (Segment3d)obj;
return s.DistanceTo(segm, out point_on_segment, out point_on_circle);
}
if (obj != null && obj.GetType() == typeof(Point3d))
{
point_on_circle = (Point3d)obj;
point_on_segment = s.ClosestPoint(point_on_circle);
return point_on_segment.DistanceTo(point_on_circle);
}
}
// Line is parallel
if (l.IsParallelTo(this))
{
point_on_segment = this.Center.ProjectionTo(l);
if (s._AxialPointLocation(point_on_segment) >= 0)
{
point_on_circle = this.ClosestPoint(point_on_segment);
return point_on_circle.DistanceTo(point_on_segment);
}
}
double dist = _distance_circle_boundary_to_line(l, out point_on_circle, out point_on_segment);
int code = s._AxialPointLocation(point_on_segment);
if (code >= 0)
{
return dist;
}
else if (code == -1)
{
point_on_circle = this.ClosestPoint(s.P1);
point_on_segment = s.P1;
}
else
{
point_on_circle = this.ClosestPoint(s.P2);
point_on_segment = s.P2;
}
return point_on_circle.DistanceTo(point_on_segment);
}
/// <summary>
/// Shortest distance between line and circle (including interior points)
/// </summary>
/// <param name="l">Target line</param>
/// <param name="p1">Closest point on circle</param>
/// <param name="p2">Closest point on line</param>
private double _distance_circle_to_line(Line3d l, out Point3d p1, out Point3d p2)
{
// Line is parallel
if (l.IsParallelTo(this))
{
p2 = this.Center.ProjectionTo(l);
p1 = this.ClosestPoint(p2);
return p1.DistanceTo(p2);
}
// Intrsecting line
object obj = l.IntersectionWith(this);
if (obj != null)
{
p1 = (Point3d)obj;
p2 = p1;
return 0;
}
return _distance_circle_boundary_to_line(l, out p1, out p2);
}
/// <summary>
/// Shortest distance between line and circle's boundary (excluding interior points)
/// (only one point will be returned for symmetrical case)
/// </summary>
/// <param name="l">Target line</param>
/// <param name="point_on_circle">Closest point on circle</param>
/// <param name="point_on_line">Closest point on line</param>
private double _distance_circle_boundary_to_line(Line3d l, out Point3d point_on_circle, out Point3d point_on_line)
{
// Line is parallel
if (l.IsParallelTo(this))
{
Plane3d plane = this.ToPlane;
Line3d line_proj = (Line3d)l.ProjectionTo(plane);
object obj = line_proj.IntersectionWith(this);
if (obj == null)
{
// Non-intersecting objects
point_on_line = this.Center.ProjectionTo(l);
point_on_circle = this.ClosestPoint(point_on_line);
return point_on_line.DistanceTo(point_on_circle);
}
else if (obj.GetType() == typeof(Point3d))
{
// Touching objects
point_on_circle = (Point3d)obj;
point_on_line = point_on_circle.ProjectionTo(l);
return point_on_line.DistanceTo(point_on_circle);
}
else
{
// Intrsecting objects, only one point will be used
Segment3d segm = (Segment3d)obj;
point_on_circle = segm.P1;
point_on_line = point_on_circle.ProjectionTo(l);
return point_on_line.DistanceTo(point_on_circle);
}
}
// Orthogonal line
if (l.IsOrthogonalTo(this))
{
Plane3d plane = this.ToPlane;
Point3d projection_point = (Point3d)l.IntersectionWith(plane);
if (projection_point == this.Center)
{
point_on_line = projection_point;
point_on_circle = this.ParametricForm(0);
return point_on_line.DistanceTo(point_on_circle);
}
else
{
Vector3d v = new Vector3d(this.Center, projection_point).Normalized;
point_on_line = projection_point;
point_on_circle = this.Center.Translate(this.R * v);
return point_on_line.DistanceTo(point_on_circle);
}
}
// General case
double d1 = 1e20;
double t1 = 0;
Point3d p;
for (int i = 0; i < 16; i++)
{
double t = i * Math.PI / 8;
p = this.ParametricForm(t);
double dist = p.DistanceTo(l);
if (dist < d1)
{
d1 = dist;
t1 = t;
}
}
double t2 = t1 - Math.PI / 8;
p = this.ParametricForm(t2);
double d2 = p.DistanceTo(l);
double t3 = t1 + Math.PI / 8;
p = this.ParametricForm(t3);
double d3 = p.DistanceTo(l);
int iter = 0;
while (d2 - d1 > 0.2 * GeometRi3D.DefaultTolerance && d1 > GeometRi3D.DefaultTolerance)
{
if (++iter > 100) break;
double ax = 2.0 * d1 / (t1 - t2) / (t1 - t3);
double aa = 0.5 * ax * (t2 + t3);
double bx = 2.0 * d2 / (t2 - t1) / (t2 - t3);
double bb = 0.5 * bx * (t1 + t3);
double cx = 2.0 * d3 / (t3 - t1) / (t3 - t2);
double cc = 0.5 * cx * (t1 + t2);
double t = (aa + bb + cc) / (ax + bx + cx);
p = this.ParametricForm(t);
double d = p.DistanceTo(l);
if (d < d1)
{
if (t > t2 & t < t1)
{
t3 = t1; d3 = d1;
}
else
{
t2 = t1; d2 = d1;
}
t1 = t; d1 = d;
}
else
{
if (t < t1)
{
t2 = t; d2 = d;
}
else
{
t3 = t; d3 = d;
}
}
}
point_on_circle = this.ParametricForm(t1);
point_on_line = point_on_circle.ProjectionTo(l);
return point_on_line.DistanceTo(point_on_circle);
}
/// <summary>
/// Shortest distance between triangle and circle (including interior points)
/// </summary>
public double DistanceTo(Triangle t)
{
Point3d point_on_circle, point_on_triangle;
return DistanceTo(t, out point_on_circle, out point_on_triangle);
}
/// <summary>
/// Shortest distance between triangle and circle (including interior points)
/// </summary>
/// <param name="t">Target triangle</param>
/// <param name="point_on_circle">Closest point on circle</param>
/// <param name="point_on_triangle">Closest point on triangle</param>
public double DistanceTo(Triangle t, out Point3d point_on_circle, out Point3d point_on_triangle)
{
double dist = this.DistanceTo(t.Plane, out point_on_circle, out point_on_triangle);
if (t.DistanceTo(point_on_triangle) <= GeometRi3D.DefaultTolerance)
{
return dist;
}
Segment3d AB = new Segment3d(t.A, t.B);
Segment3d BC = new Segment3d(t.B, t.C);
Segment3d AC = new Segment3d(t.A, t.C);
dist = this.DistanceTo(AB, out point_on_circle, out point_on_triangle);
Point3d point_on_circle2, point_on_triangle2;
double dist2 = this.DistanceTo(BC, out point_on_circle2, out point_on_triangle2);
if (dist2 < dist)
{
dist = dist2;
point_on_circle = point_on_circle2;
point_on_triangle = point_on_triangle2;
}
dist2 = this.DistanceTo(AC, out point_on_circle2, out point_on_triangle2);
if (dist2 < dist)
{
dist = dist2;
point_on_circle = point_on_circle2;
point_on_triangle = point_on_triangle2;
}
return dist;
}
/// <summary>
/// Shortest distance from circle to box
/// </summary>
public double DistanceTo(Box3d box)
{
return box.DistanceTo(this);
}
/// <summary>
/// Shortest distance from circle to convex polyhedron
/// </summary>
public double DistanceTo(ConvexPolyhedron cp)
{
return cp.DistanceTo(this);
}
#endregion
/// <summary>
/// Intersection check between circle and sphere
/// </summary>
public bool Intersects(Sphere s)
{
if (this._point.DistanceTo(s.Center) <= this.R + s.R)
{
Object obj = s.IntersectionWith(this.ToPlane);
if (obj != null && obj.GetType() == typeof(Circle3d))
{
// Check for circle-circle intersection
if (this.IntersectionWith((Circle3d)obj) != null)
return true;
}
else if (obj != null && obj.GetType() == typeof(Point3d))
{
return ((Point3d)obj).BelongsTo(this);
}
else
{
return false;
}
}
return false;
}
/// <summary>
/// Intersection check between two circles
/// </summary>
public bool Intersects(Circle3d c)
{
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * Max(this.R, c.R);
GeometRi3D.UseAbsoluteTolerance = true;
bool result = this.Intersects(c);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
// Early exit (separated circles)
double d = this._point.DistanceTo(c._point);
if (d > this.R + c.R + GeometRi3D.Tolerance)
return false;
//this._normal.IsParallelTo(c._normal)
if (GeometRi3D.AlmostEqual(Abs(this._normal * c._normal), 1.0))
{
if (this._point.BelongsTo(new Plane3d(c._point, c._normal)))
{
// Coplanar objects
if (d <= this.R + c.R + GeometRi3D.Tolerance)
{
return true;
}
else
{
return false;
}
}
else
{
// parallel objects
return false;
}
}
else
{
// Check 3D intersection
Vector3d v = new Vector3d(this._point, c._point);
double this_norm = this._normal.Norm;
double c_norm = c._normal.Norm;
double cos_angle1 = this._normal * v / this_norm / d;
double delta1 = Abs(d * cos_angle1);
double sin_angle2 = this._normal.Cross(c._normal).Norm / this_norm / c_norm;
double delta2 = Abs(c.R * sin_angle2);
if (delta1 > delta2) return false;
cos_angle1 = c._normal * v / c_norm / d;
delta1 = Abs(d * cos_angle1);
delta2 = Abs(this.R * sin_angle2);
if (delta1 > delta2) return false;
return _circle_circle_intersection_check_2(c);
}
}
private bool _circle_circle_intersection_check_2(Circle3d c)
{
Segment3d segm;
double dist;
Object obj = this.IntersectionWith(c.ToPlane);
if (obj == null) return false;
if (obj != null && obj.GetType() == typeof(Point3d))
{
Point3d point = (Point3d)obj;
dist = c.Center.DistanceTo(point);
}
else
{
segm = (Segment3d)obj;
dist = c.Center.DistanceTo(segm);
}
if (dist <= c.R + GeometRi3D.Tolerance)
{
return true;
}
else
{
return false;
}
}
private bool _circle_circle_intersection_check(Circle3d c)
{
Plane3d plane_this = new Plane3d(this._point, this._normal);
Line3d l = (Line3d)plane_this.IntersectionWith(new Plane3d(c._point, c._normal));
Coord3d local_coord = new Coord3d(this._point, l.Direction, this._normal.Cross(l.Direction));
Point3d p = l.Point.ConvertTo(local_coord);
if (GeometRi3D.Greater(Abs(p.Y), this.R))
{
// No intersection
return false;
}
else if (GeometRi3D.AlmostEqual(Abs(p.Y), this.R))
{
// Intersection in one point
Point3d pp = new Point3d(0, p.Y, 0, local_coord);
if (pp.DistanceTo(c._point) <= c.R + GeometRi3D.Tolerance)
{
return true;
}
else
{
return false;
}
}
else
{
double dd = Sqrt(this.R * this.R - p.Y * p.Y);
Point3d p1 = new Point3d(-dd, p.Y, 0, local_coord);
Point3d p2 = new Point3d(dd, p.Y, 0, local_coord);
// check if at least one point is outside circle "c"
if (p1.DistanceTo(c._point) <= c.R + GeometRi3D.Tolerance) return true;
// Now check if segment (p1,p2) intrsects circle "c"
// Use local coord with center in c.Point and X-axis aligned with segment
local_coord = new Coord3d(c._point, l.Direction, c._normal.Cross(l.Direction));
p1 = p1.ConvertTo(local_coord);
p2 = p2.ConvertTo(local_coord);
// use parametric form
// x=t*x1+(1-t)x2
// y=t*y1+(1-t)y2
// and take into account that y1=y2, x0=y0=0
double aa = (p1.X - p2.X) * (p1.X - p2.X);
double bb = 2 * p2.X * (p1.X - p2.X);
double cc = p2.X * p2.X + p2.Y * p2.Y - c.R * c.R;
double discr = bb * bb - 4 * aa * cc;
if (discr < 0)
{
return false;
}
else
{
discr = Sqrt(discr);
double t1 = (-bb + discr) / (2 * aa);
double t2 = (-bb - discr) / (2 * aa);
if ((t1 >= 0 && t1 <= 1) || (t2 >= 0 && t2 <= 1))
{
return true;
}
else
{
return false;
}
}
}
}
/// <summary>
/// Intersection check between circle and triangle
/// </summary>
public bool Intersects(Triangle t)
{
Plane3d t_plane = t.Plane;
if (this.DistanceTo(t_plane) > 0) return false;
if (this.IsCoplanarTo(t))
{
if (t.A.DistanceTo(this._point) <= this._r) return true;
if (t.B.DistanceTo(this._point) <= this._r) return true;
if (t.C.DistanceTo(this._point) <= this._r) return true;
if (this._point.BelongsTo(t)) return true;
if (this.IntersectionWith(new Segment3d(t.A, t.B)) != null) return true;
if (this.IntersectionWith(new Segment3d(t.B, t.C)) != null) return true;
if (this.IntersectionWith(new Segment3d(t.C, t.A)) != null) return true;
}
object obj = this.IntersectionWith(t_plane);
if (obj != null && obj.GetType() == typeof(Point3d))
{
return ((Point3d)obj).BelongsTo(t);
}
else if (obj != null && obj.GetType() == typeof(Segment3d))
{
return ((Segment3d)obj).IntersectionWith(t) != null;
}
return false;
}
/// <summary>
/// Intersection check between circle and box
/// </summary>
public bool Intersects(Box3d box)
{
return box.Intersects(this);
}
/// <summary>
/// Intersection check between circle and segment
/// </summary>
public bool Intersects(Segment3d s)
{
return this.IntersectionWith(s) != null;
}
/// <summary>
/// Orthogonal projection of the circle to plane
/// </summary>
public Ellipse ProjectionTo(Plane3d s)
{
return this.ToEllipse.ProjectionTo(s);
}
/// <summary>
/// Orthogonal projection of the circle to line
/// </summary>
public Segment3d ProjectionTo(Line3d l)
{
double s = _r * Cos(l.AngleTo(this));
Vector3d v = l.Direction.Normalized;
Point3d p = _point.ProjectionTo(l);
return new Segment3d(p.Translate(-s * v), p.Translate(s * v));
}
/// <summary>
/// Intersection of circle with line.
/// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Line3d l)
{
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.R;
GeometRi3D.UseAbsoluteTolerance = true;
object result = this.IntersectionWith(l);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
if (l.Direction.IsOrthogonalTo(this._normal))
{
if (l.Point.BelongsTo(new Plane3d(this._point, this._normal)))
{
// coplanar objects
// Find intersection of line and circle (2D)
// Local coord: X - line direction, Z - circle normal
Coord3d local_coord = new Coord3d(this._point, l.Direction, this._normal.Cross(l.Direction));
Point3d p = l.Point.ConvertTo(local_coord);
double c = p.Y;
if (Abs(c) > this.R + GeometRi3D.Tolerance)
{
return null;
}
else if (Abs(c) < this.R)
{
double x1 = Sqrt(this.R * this.R - Abs(c) * Abs(c));
double x2 = -x1;
return new Segment3d(new Point3d(x1, c, 0, local_coord), new Point3d(x2, c, 0, local_coord));
}
else if (c > 0)
{
return new Point3d(0, this.R, 0, local_coord);
}
else
{
return new Point3d(0, -this.R, 0, local_coord);
}
}
else
{
// parallel objects
return null;
}
}
else
{
// Line intersects circle' plane
Point3d p = (Point3d)l.IntersectionWith(new Plane3d(this._point, this._normal));
if (p.DistanceTo(this._point) < this.R + GeometRi3D.Tolerance)
{
return p;
}
else
{
return null;
}
}
}
/// <summary>
/// Intersection of circle with segment.
/// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Segment3d s)
{
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.R;
GeometRi3D.UseAbsoluteTolerance = true;
object result = this.IntersectionWith(s);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
object obj = this.IntersectionWith(s.Line);
if (obj == null)
{
return null;
}
else if (obj.GetType() == typeof(Point3d))
{
Point3d p = (Point3d)obj;
if (p.BelongsTo(s))
{
return p;
}
else
{
return null;
}
}
else
{
return s.IntersectionWith((Segment3d)obj);
}
}
/// <summary>
/// Intersection of circle with ray.
/// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Ray3d r)
{
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.R;
GeometRi3D.UseAbsoluteTolerance = true;
object result = this.IntersectionWith(r);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
object obj = this.IntersectionWith(r.ToLine);
if (obj == null)
{
return null;
}
else if (obj.GetType() == typeof(Point3d))
{
Point3d p = (Point3d)obj;
if (p.BelongsTo(r))
{
return p;
}
else
{
return null;
}
}
else
{
return r.IntersectionWith((Segment3d)obj);
}
}
/// <summary>
/// Intersection of circle with plane.
/// Returns 'null' (no intersection) or object of type 'Circle3d', 'Point3d' or 'Segment3d'.
/// </summary>
public object IntersectionWith(Plane3d s)
{
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.R;
GeometRi3D.UseAbsoluteTolerance = true;
object result = this.IntersectionWith(s);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
if (this._normal.IsParallelTo(s.Normal))
{
if (this._point.BelongsTo(s))
{
// coplanar objects
return this.Copy();
}
else
{
// parallel objects
return null;
}
}
else
{
Vector3d v1 = this._normal.Cross(s.Normal);
Vector3d v2 = this._normal.Cross(v1);
Line3d l = new Line3d(this._point, v2);
Point3d intersection_point = (Point3d)l.IntersectionWith(s);
double dist = intersection_point.DistanceTo(this.Center);
if (Abs(R - dist) <= GeometRi3D.DefaultTolerance)
{
// Point
return intersection_point;
}
else if (R - dist > 0)
{
// Segment
double half_length = Sqrt(R * R - dist * dist);
v1 = v1.Normalized;
Point3d p1 = intersection_point.Translate(half_length * v1);
Point3d p2 = intersection_point.Translate(-half_length * v1);
return new Segment3d(p1, p2);
}
else
{
return null;
}
}
}
/// <summary>
/// Intersection of two circles.
/// Returns 'null' (no intersection) or object of type 'Circle3d', 'Point3d' or 'Segment3d'.
/// In 2D (coplanar circles) the segment will define two intersection points.
/// </summary>
public object IntersectionWith(Circle3d c)
{
// Relative tolerance ================================
if (!GeometRi3D.UseAbsoluteTolerance)
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * Max(this.R, c.R);
GeometRi3D.UseAbsoluteTolerance = true;
object result = this.IntersectionWith(c);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
//====================================================
// Early exit (separated circles)
double d = this._point.DistanceTo(c._point);
if (d > this.R + c.R + GeometRi3D.Tolerance)
return null;
if (this._normal.IsParallelTo(c._normal))
{
if (this._point.BelongsTo(new Plane3d(c._point, c._normal)))
{
// Coplanar objects
// Search 2D intersection of two circles
// Equal circles
if (GeometRi3D.AlmostEqual(d, 0) && GeometRi3D.AlmostEqual(this.R, c.R))
{
return this.Copy();
}
// One circle inside the other
if (d < Abs(this.R - c.R) - GeometRi3D.Tolerance)
{
if (this.R > c.R)
{
return c.Copy();
}
else
{
return this.Copy();
}
}
// Outer tangency
if (GeometRi3D.AlmostEqual(d, this.R + c.R))
{
Vector3d vec = new Vector3d(this._point, c._point);
return this._point.Translate(this.R * vec.Normalized);
}
// Inner tangency
if (Abs(Abs(this.R - c.R) - d) < GeometRi3D.Tolerance)
{
Vector3d vec = new Vector3d(this._point, c._point);
if (this.R > c.R)
{
return this._point.Translate(this.R * vec.Normalized);
}
else
{
return this._point.Translate(-this.R * vec.Normalized);
}
}
// intersecting circles
// Create local CS with origin in circle's center
Vector3d vec1 = new Vector3d(this._point, c._point);
Vector3d vec2 = vec1.Cross(this._normal);
Coord3d local_cs = new Coord3d(this._point, vec1, vec2);
double x = 0.5 * (d * d - c.R * c.R + this.R * this.R) / d;
double y = 0.5 * Sqrt((-d + c.R - this.R) * (-d - c.R + this.R) * (-d + c.R + this.R) * (d + c.R + this.R)) / d;
Point3d p1 = new Point3d(x, y, 0, local_cs);
Point3d p2 = new Point3d(x, -y, 0, local_cs);
return new Segment3d(p1, p2);
}
else
{
// parallel objects
return null;
}
}
else
{
// Check 3D intersection
Vector3d v = new Vector3d(this._point, c._point);
double this_norm = this._normal.Norm;
double c_norm = c._normal.Norm;
double cos_angle1 = this._normal * v / this_norm / d;
double delta1 = Abs(d * cos_angle1);
double sin_angle2 = this._normal.Cross(c._normal).Norm / this_norm / c_norm;
double delta2 = Abs(c.R * sin_angle2);
if (delta1 > delta2) return null;
cos_angle1 = c._normal * v / c_norm / d;
delta1 = Abs(d * cos_angle1);
delta2 = Abs(this.R * sin_angle2);
if (delta1 > delta2) return null;
Plane3d plane_this = new Plane3d(this._point, this._normal);
object obj = c.IntersectionWith(plane_this);
if (obj == null)
{
return null;
}
else if (obj.GetType() == typeof(Point3d))
{
Point3d p = (Point3d)obj;
if (p.DistanceTo(this._point) < this.R + GeometRi3D.Tolerance)
{
return p;
}
else
{
return null;
}
}
else
{
Segment3d s = (Segment3d)obj;
return s.IntersectionWith(this);
}
}
}
internal override int _PointLocation(Point3d p)
{
if (GeometRi3D.UseAbsoluteTolerance)
{
Plane3d s = new Plane3d(this.Center, this.Normal);
Point3d proj = p.ProjectionTo(s);
if (GeometRi3D.AlmostEqual(p.DistanceTo(proj), 0))
{
if ( GeometRi3D.Smaller(p.DistanceTo(this.Center), this.R))
{
return 1; // Point is strictly inside
}
else if (GeometRi3D.AlmostEqual(p.DistanceTo(this.Center), this.R) )
{
return 0; // Point is on boundary
}
else
{
return -1; // Point is outside
}
}
else
{
return -1; // Point is outside
}
}
else
{
double tol = GeometRi3D.Tolerance;
GeometRi3D.Tolerance = tol * this.R;
GeometRi3D.UseAbsoluteTolerance = true;
int result = this._PointLocation(p);
GeometRi3D.UseAbsoluteTolerance = false;
GeometRi3D.Tolerance = tol;
return result;
}
}
#region "AngleTo"
/// <summary>
/// Angle between two objects in radians (0 < angle < Pi)
/// </summary>
public double AngleTo(ILinearObject obj)
{
return GeometRi3D.GetAngle(this, obj);
}
/// <summary>
/// Angle between two objects in degrees (0 < angle < 180)
/// </summary>
public double AngleToDeg(ILinearObject obj)
{
return AngleTo(obj) * 180 / PI;
}
/// <summary>
/// Angle between two objects in radians (0 < angle < Pi)
/// </summary>
public double AngleTo(IPlanarObject obj)
{
return GeometRi3D.GetAngle(this, obj);
}
/// <summary>
/// Angle between two objects in degrees (0 < angle < 180)
/// </summary>
public double AngleToDeg(IPlanarObject obj)
{
return AngleTo(obj) * 180 / PI;
}
#endregion
#region "TranslateRotateReflect"
/// <summary>
/// Translate circle by a vector
/// </summary>
public Circle3d Translate(Vector3d v)
{
return new Circle3d(this.Center.Translate(v), this.R, this.Normal);
}
/// <summary>
/// Rotate circle by a given rotation matrix
/// </summary>
[System.Obsolete("use Rotation object and specify rotation center: this.Rotate(Rotation r, Point3d p)")]
public Circle3d Rotate(Matrix3d m)
{
return new Circle3d(this.Center.Rotate(m), this.R, this.Normal.Rotate(m));
}
/// <summary>
/// Rotate circle by a given rotation matrix around point 'p' as a rotation center
/// </summary>
[System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d p)")]
public Circle3d Rotate(Matrix3d m, Point3d p)
{
return new Circle3d(this.Center.Rotate(m, p), this.R, this.Normal.Rotate(m));
}
/// <summary>
/// Rotate circle around point 'p' as a rotation center
/// </summary>
public Circle3d Rotate(Rotation r, Point3d p)
{
return new Circle3d(this.Center.Rotate(r, p), this.R, this.Normal.Rotate(r));
}
/// <summary>
/// Reflect circle in given point
/// </summary>
public Circle3d ReflectIn(Point3d p)
{
return new Circle3d(this.Center.ReflectIn(p), this.R, this.Normal.ReflectIn(p));
}
/// <summary>
/// Reflect circle in given line
/// </summary>
public Circle3d ReflectIn(Line3d l)
{
return new Circle3d(this.Center.ReflectIn(l), this.R, this.Normal.ReflectIn(l));
}
/// <summary>
/// Reflect circle in given plane
/// </summary>
public Circle3d ReflectIn(Plane3d s)
{
return new Circle3d(this.Center.ReflectIn(s), this.R, this.Normal.ReflectIn(s));
}
/// <summary>
/// Scale circle relative to given point
/// </summary>
public virtual Circle3d Scale(double scale, Point3d scaling_center)
{
Point3d new_center = scaling_center + scale * (this.Center - scaling_center);
return new Circle3d(new_center, this._r * scale, this._normal);
}
#endregion
/// <summary>
/// Determines whether two objects are equal.
/// </summary>
public override bool Equals(object obj)
{
if (obj == null || (!object.ReferenceEquals(this.GetType(), obj.GetType())))
{
return false;
}
Circle3d c = (Circle3d)obj;
if (GeometRi3D.UseAbsoluteTolerance)
{
return c.Center == this.Center && Abs(c.R - this.R) <= GeometRi3D.Tolerance && c.Normal.IsParallelTo(this.Normal);
}
else
{
return Abs(c.Center.DistanceTo(this.Center)) / this.R <= GeometRi3D.Tolerance &&
Abs(c.R - this.R) / this.R <= GeometRi3D.Tolerance &&
c.Normal.IsParallelTo(this.Normal);
}
}
/// <summary>
/// Returns the hashcode for the object.
/// </summary>
public override int GetHashCode()
{
return GeometRi3D.HashFunction(_point.GetHashCode(), _r.GetHashCode(), _normal.GetHashCode());
}
/// <summary>
/// String representation of an object in global coordinate system.
/// </summary>
public override String ToString()
{
return ToString(Coord3d.GlobalCS, false);
}
/// <summary>
/// String representation of an object in global coordinate system.
/// </summary>
public String ToString(bool full_precision = false)
{
return ToString(Coord3d.GlobalCS, full_precision);
}
/// <summary>
/// String representation of an object in reference coordinate system.
/// </summary>
public String ToString(Coord3d coord, bool full_precision = false)
{
string nl = System.Environment.NewLine;
if (coord == null) { coord = Coord3d.GlobalCS; }
Point3d P = _point.ConvertTo(coord);
Vector3d normal = _normal.ConvertTo(coord);
string str = string.Format("Circle: ") + nl;
if (full_precision)
{
str += string.Format(" Center -> ({0}, {1}, {2})", P.X, P.Y, P.Z) + nl;
str += string.Format(" Radius -> {0}", _r) + nl;
str += string.Format(" Normal -> ({0}, {1}, {2})", normal.X, normal.Y, normal.Z);
}
else
{
str += string.Format(" Center -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", P.X, P.Y, P.Z) + nl;
str += string.Format(" Radius -> {0,10:g5}", _r) + nl;
str += string.Format(" Normal -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", normal.X, normal.Y, normal.Z);
}
return str;
}
public String ToString(Coord3d coord, bool full_precision = false, bool code = true)
{
string nl = System.Environment.NewLine;
if (coord == null) { coord = Coord3d.GlobalCS; }
Point3d P = _point.ConvertTo(coord);
Vector3d normal = _normal.ConvertTo(coord);
string str = string.Format("Circle3d circle = new Circle3d(new Point3d({0}, {1}, {2}), {3}, new Vector3d({4}, {5}, {6}));",
P.X, P.Y, P.Z, this.R, normal.X, normal.Y, normal.Z) + nl;
return str;
}
// Operators overloads
//-----------------------------------------------------------------
public static bool operator ==(Circle3d c1, Circle3d c2)
{
if (object.ReferenceEquals(c1, null))
return object.ReferenceEquals(c2, null);
return c1.Equals(c2);
}
public static bool operator !=(Circle3d c1, Circle3d c2)
{
if (object.ReferenceEquals(c1, null))
return !object.ReferenceEquals(c2, null);
return !c1.Equals(c2);
}
}
}
================================================
FILE: GeometRi/ConvexPolyhedron.cs
================================================
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace GeometRi
{
/// <summary>
/// Convex polyhedron with counterclockwise oriented faces (seen from outside).
/// </summary>
#if NET20_OR_GREATER
[Serializable]
#endif
public class ConvexPolyhedron : FiniteObject, IFiniteObject
{
public int numVertices, numEdges, numFaces;
public Point3d[] vertex;
public Edge[] edge;
public Face[] face;
private AABB _aabb = null;
private List<Segment3d> _list_e = null;
/// <summary>
/// Edge of a convex polyhedron.
/// </summary>
#if NET20_OR_GREATER
[Serializable]
#endif
public struct Edge
{
public int p1, p2;
internal ConvexPolyhedron parent;
public Edge(int P1, int P2)
{
p1 = P1;
p2 = P2;
parent = null;
}
public Point3d P1
{
get
{
return parent.vertex[p1];
}
}
public Point3d P2
{
get
{
return parent.vertex[p2];
}
}
}
public interface IVertex
{
Point3d this[int index] { get; }
}
#if NET20_OR_GREATER
[Serializable]
#endif
public struct Face : IVertex
{
public int numVertices;
public int[] vertex;
public Vector3d normal;
internal ConvexPolyhedron parent;
public Face(int numVertices, int[] vertex)
{
this.numVertices = numVertices;
this.vertex = vertex;
parent = null;
normal = null;
}
public double Area
{
get
{
Vector3d v1, v2;
v1 = new Vector3d(parent.vertex[vertex[0]], parent.vertex[vertex[1]]);
double area = 0;
for (int i = 0; i < vertex.Length - 2; i++)
{
v2 = new Vector3d(parent.vertex[vertex[0]], parent.vertex[vertex[i + 2]]);
area += v1.Cross(v2).Norm;
v1 = v2;
}
return area / 2;
}
}
public Point3d Center
{
get
{
Point3d center = new Point3d(); ;
foreach (int v in vertex)
{
center += parent.vertex[v];
}
return center / vertex.Length;
}
}
/// <summary>
/// Create prism by extruding face of convex polyhedron in the direction of face normal
/// </summary>
public ConvexPolyhedron Extrude(double distance, bool symmetrical = false)
{
return Extrude(normal, distance, symmetrical);
}
/// <summary>
/// Create prism by extruding face of convex polyhedron
/// </summary>
public ConvexPolyhedron Extrude(Vector3d direction, double distance, bool symmetrical = false)
{
Point3d[] new_vertices = new Point3d[numVertices * 2];
Edge[] edges = new Edge[numVertices * 3];
Face[] faces = new Face[numVertices + 2];
Vector3d traslation_vec = direction.Normalized * distance;
for (int i = 0; i < numVertices; i++)
{
new_vertices[i] = parent.vertex[vertex[i]].Copy();
new_vertices[i + numVertices] = parent.vertex[vertex[i]].Translate(traslation_vec);
}
faces[0] = new Face(numVertices, new int[numVertices]);
faces[1] = new Face(numVertices, new int[numVertices]);
for (int i = 0; i < numVertices; i++)
{
faces[0].vertex[i] = i;
faces[1].vertex[i] = i + numVertices;
if (i < numVertices - 1)
{
// regilar side face
faces[i + 2] = new Face(4, new int[] { i, i + 1, i + 1 + numVertices, i + numVertices });
edges[i] = new Edge(i, i + 1);
edges[i + numVertices] = new Edge(i + numVertices, i + 1 + numVertices);
edges[i + numVertices * 2] = new Edge(i, i + numVertices);
}
else
{
// last side face
faces[i + 2] = new Face(4, new int[] { i, 0, numVertices, i + numVertices });
edges[i] = new Edge(i, 0);
edges[i + numVertices] = new Edge(i + numVertices, numVertices);
edges[i + numVertices * 2] = new Edge(i, i + numVertices);
}
}
ConvexPolyhedron cp = new ConvexPolyhedron(numVertices * 2, numVertices * 3, numVertices + 2, new_vertices, edges, faces);
cp.CheckFaceOrientation();
if (symmetrical)
{
cp = cp.Translate(-traslation_vec / 2);
}
return cp;
}
Point3d IVertex.this[int index]
{
get
{
return parent.vertex[vertex[index]];
}
}
/// <summary>
/// Returns a Point3d object for vertex [i]
/// </summary>
public IVertex Vertex
{
get
{
return this;
}
}
internal void UpdateNormal()
{
normal = new Vector3d(parent.vertex[vertex[0]], parent.vertex[vertex[1]]).Cross(new Vector3d(parent.vertex[vertex[0]], parent.vertex[vertex[2]])).Normalized;
}
}
#region "Constructors"
/// <summary>
/// Creates general convex polyhedron from a lists of vertices, edges, and faces
/// </summary>
/// <param name="numVertices">Number of vertices</param>
/// <param name="numEdges">Number of edges</param>
/// <param name="numFaces">Number of faces</param>
/// <param name="vertices">List of vertices</param>
/// <param name="edges">List of edges</param>
/// <param name="faces">List of faces</param>
/// <param name="check_face_orientation">Check and invert incorrectly oriented faces</param>
public ConvexPolyhedron(int numVertices, int numEdges, int numFaces, Point3d[] vertices, Edge[] edges, Face[] faces, bool check_face_orientation = false)
{
this.numVertices = numVertices;
this.numEdges = numEdges;
this.numFaces = numFaces;
this.vertex = vertices;
this.edge = edges;
this.face = faces;
// Initialize fields
for (int i = 0; i < edges.Length; i++)
{
edges[i].parent = this;
}
for (int i = 0; i < faces.Length; i++)
{
faces[i].parent = this;
faces[i].UpdateNormal();
}
if (check_face_orientation)
{
CheckFaceOrientation();
}
}
/// <summary>
/// Create ConvexPolyhedron object from a Tetrahedron object
/// </summary>
public static ConvexPolyhedron FromTetrahedron(Tetrahedron t)
{
Point3d[] vertices = new Point3d[4];
vertices[0] = t.A.Copy();
vertices[1] = t.B.Copy();
vertices[2] = t.C.Copy();
vertices[3] = t.D.Copy();
Edge[] edges = new Edge[6];
edges[0] = new Edge(0, 1);
edges[1] = new Edge(1, 2);
edges[2] = new Edge(2, 0);
edges[3] = new Edge(0, 3);
edges[4] = new Edge(1, 3);
edges[5] = new Edge(2, 3);
Face[] faces = new Face[4];
faces[0] = new Face(3, new int[] { 0, 1, 2 });
faces[1] = new Face(3, new int[] { 0, 1, 3 });
faces[2] = new Face(3, new int[] { 1, 2, 3 });
faces[3] = new Face(3, new int[] { 2, 0, 3 });
ConvexPolyhedron cp = new ConvexPolyhedron(4, 6, 4, vertices, edges, faces);
cp.CheckFaceOrientation();
return cp;
}
public static ConvexPolyhedron Cube(Point3d p_min, Point3d p_max)
{
return FromBox(new Box3d(p_min, p_max));
}
/// <summary>
/// Create ConvexPolyhedron object from a Box3d object
/// </summary>
public static ConvexPolyhedron FromBox(Box3d box)
{
Point3d[] vertices = new Point3d[8];
vertices[0] = box.P1.Copy();
vertices[1] = box.P2.Copy();
vertices[2] = box.P3.Copy();
vertices[3] = box.P4.Copy();
vertices[4] = box.P5.Copy();
vertices[5] = box.P6.Copy();
vertices[6] = box.P7.Copy();
vertices[7] = box.P8.Copy();
Edge[] edges = new Edge[12];
edges[0] = new Edge(0, 1);
edges[1] = new Edge(1, 2);
edges[2] = new Edge(2, 3);
edges[3] = new Edge(3, 0);
edges[4] = new Edge(4, 5);
edges[5] = new Edge(5, 6);
edges[6] = new Edge(6, 7);
edges[7] = new Edge(7, 4);
edges[8] = new Edge(0, 4);
edges[9] = new Edge(1, 5);
edges[10] = new Edge(2, 6);
edges[11] = new Edge(3, 7);
Face[] faces = new Face[6];
faces[0] = new Face(4, new int[] { 0, 3, 2, 1 });
faces[1] = new Face(4, new int[] { 4, 5, 6, 7 });
faces[2] = new Face(4, new int[] { 0, 1, 5, 4 });
faces[3] = new Face(4, new int[] { 2, 3, 7, 6 });
faces[4] = new Face(4, new int[] { 1, 2, 6, 5 });
faces[5] = new Face(4, new int[] { 0, 4, 7, 3 });
return new ConvexPolyhedron(8, 12, 6, vertices, edges, faces);
}
/// <summary>
/// Creates regular octahedron centered at origin with vertices:
/// <para>(±1, 0, 0)</para>
/// <para>( 0, ±1, 0)</para>
/// <para>( 0, 0, ±1)</para>
/// </summary>
public static ConvexPolyhedron Octahedron()
{
Point3d[] vertices = new Point3d[6];
vertices[0] = new Point3d(1, 0, 0);
vertices[1] = new Point3d(-1, 0, 0);
vertices[2] = new Point3d(0, 1, 0);
vertices[3] = new Point3d(0, -1, 0);
vertices[4] = new Point3d(0, 0, 1);
vertices[5] = new Point3d(0, 0, -1);
Edge[] edges = new Edge[12];
edges[0] = new Edge(0, 2);
edges[1] = new Edge(2, 1);
edges[2] = new Edge(1, 3);
edges[3] = new Edge(3, 0);
edges[4] = new Edge(0, 4);
edges[5] = new Edge(2, 4);
edges[6] = new Edge(1, 4);
edges[7] = new Edge(3, 4);
edges[8] = new Edge(0, 5);
edges[9] = new Edge(2, 5);
edges[10] = new Edge(1, 5);
edges[11] = new Edge(3, 5);
Face[] faces = new Face[8];
faces[0] = new Face(3, new int[] { 0, 2, 4 });
faces[1] = new Face(3, new int[] { 2, 1, 4 });
faces[2] = new Face(3, new int[] { 1, 3, 4 });
faces[3] = new Face(3, new int[] { 3, 0, 4 });
faces[4] = new Face(3, new int[] { 0, 3, 5 });
faces[5] = new Face(3, new int[] { 3, 1, 5 });
faces[6] = new Face(3, new int[] { 1, 2, 5 });
faces[7] = new Face(3, new int[] { 2, 0, 5 });
return new ConvexPolyhedron(6, 12, 8, vertices, edges, faces);
}
/// <summary>
/// Creates regular icosahedron centered at origin with vertices:
/// <para>( 0, ±f, ±1)</para>
/// <para>(±f, ±1, 0)</para>
/// <para>(±1, 0, ±f)</para>
/// <para>with 'f' equal to golden ratio (1+Sqrt(5))/2</para>
/// </summary>
public static ConvexPolyhedron Icosahedron()
{
double f = (1 + Math.Sqrt(5)) / 2;
Point3d[] vertices = new Point3d[12];
vertices[0] = new Point3d(0, f, 1);
vertices[1] = new Point3d(0, f, -1);
vertices[2] = new Point3d(0, -f, 1);
vertices[3] = new Point3d(0, -f, -1);
vertices[4] = new Point3d(f, 1, 0);
vertices[5] = new Point3d(f, -1, 0);
vertices[6] = new Point3d(-f, 1, 0);
vertices[7] = new Point3d(-f, -1, 0);
vertices[8] = new Point3d(1, 0, f);
vertices[9] = new Point3d(-1, 0, f);
vertices[10] = new Point3d(1, 0, -f);
vertices[11] = new Point3d(-1, 0, -f);
Edge[] edges = new Edge[30];
edges[0] = new Edge(0, 1);
edges[1] = new Edge(0, 4);
edges[2] = new Edge(0, 6);
edges[3] = new Edge(0, 8);
edges[4] = new Edge(0, 9);
edges[5] = new Edge(1, 4);
edges[6] = new Edge(1, 6);
edges[7] = new Edge(1, 10);
edges[8] = new Edge(1, 11);
edges[9] = new Edge(2, 3);
edges[10] = new Edge(2, 5);
edges[11] = new Edge(2, 7);
edges[12] = new Edge(2, 8);
edges[13] = new Edge(2, 9);
edges[14] = new Edge(3, 5);
edges[15] = new Edge(3, 7);
edges[16] = new Edge(3, 10);
edges[17] = new Edge(3, 11);
edges[18] = new Edge(4, 5);
edges[19] = new Edge(4, 8);
edges[20] = new Edge(4, 10);
edges[21] = new Edge(5, 8);
edges[22] = new Edge(5, 10);
edges[23] = new Edge(6, 7);
edges[24] = new Edge(6, 9);
edges[25] = new Edge(6, 11);
edges[26] = new Edge(7, 9);
edges[27] = new Edge(7, 11);
edges[28] = new Edge(8, 9);
edges[29] = new Edge(10, 11);
Face[] faces = new Face[20];
faces[0] = new Face(3, new int[] { 0, 4, 1 });
faces[1] = new Face(3, new int[] { 0, 1, 6 });
faces[2] = new Face(3, new int[] { 0, 6, 9 });
faces[3] = new Face(3, new int[] { 0, 9, 8 });
faces[4] = new Face(3, new int[] { 0, 8, 4 });
faces[5] = new Face(3, new int[] { 1, 4, 10 });
faces[6] = new Face(3, new int[] { 1, 10, 11 });
faces[7] = new Face(3, new int[] { 1, 11, 6 });
faces[8] = new Face(3, new int[] { 2, 3, 5 });
faces[9] = new Face(3, new int[] { 2, 5, 8 });
faces[10] = new Face(3, new int[] { 2, 8, 9 });
faces[11] = new Face(3, new int[] { 2, 9, 7 });
faces[12] = new Face(3, new int[] { 2, 7, 3 });
faces[13] = new Face(3, new int[] { 3, 10, 5 });
faces[14] = new Face(3, new int[] { 3, 7, 11 });
faces[15] = new Face(3, new int[] { 3, 11, 10 });
faces[16] = new Face(3, new int[] { 4, 8, 5 });
faces[17] = new Face(3, new int[] { 4, 5, 10 });
faces[18] = new Face(3, new int[] { 6, 7, 9 });
faces[19] = new Face(3, new int[] { 6, 11, 7 });
return new ConvexPolyhedron(12, 30, 20, vertices, edges, faces);
}
/// <summary>
/// Creates regular dodecahedron centered at origin with vertices:
/// <para>(±1, ±1, ±1)</para>
/// <para>( 0, ±φ, ±1/φ)</para>
/// <para>(±φ, ±1/φ, 0)</para>
/// <para>(±1/φ, 0, ±φ)</para>
/// <para>with 'φ' equal to golden ratio (1+Sqrt(5))/2</para>
/// </summary>
public static ConvexPolyhedron Dodecahedron()
{
double f = (1 + Math.Sqrt(5)) / 2;
Point3d[] vertices = new Point3d[20];
vertices[0] = new Point3d(-1, 1, 1);
vertices[1] = new Point3d(-1, -1, 1);
vertices[2] = new Point3d(1, -1, 1);
vertices[3] = new Point3d(1, 1, 1);
vertices[4] = new Point3d(-1, 1, -1);
vertices[5] = new Point3d(-1, -1, -1);
vertices[6] = new Point3d(1, -1, -1);
vertices[7] = new Point3d(1, 1, -1);
vertices[8] = new Point3d(0, f, 1 / f);
vertices[9] = new Point3d(0, -f, 1 / f);
vertices[10] = new Point3d(0, f, -1 / f);
vertices[11] = new Point3d(0, -f, -1 / f);
vertices[12] = new Point3d(f, 1 / f, 0);
vertices[13] = new Point3d(f, -1 / f, 0);
vertices[14] = new Point3d(-f, 1 / f, 0);
vertices[15] = new Point3d(-f, -1 / f, 0);
vertices[16] = new Point3d(1 / f, 0, f);
vertices[17] = new Point3d(-1 / f, 0, f);
vertices[18] = new Point3d(1 / f, 0, -f);
vertices[19] = new Point3d(-1 / f, 0, -f);
Edge[] edges = new Edge[30];
edges[0] = new Edge(0, 8);
edges[1] = new Edge(0, 14);
edges[2] = new Edge(0, 17);
edges[3] = new Edge(1, 9);
edges[4] = new Edge(1, 15);
edges[5] = new Edge(1, 17);
edges[6] = new Edge(2, 9);
edges[7] = new Edge(2, 13);
edges[8] = new Edge(2, 16);
edges[9] = new Edge(3, 8);
edges[10] = new Edge(3, 12);
edges[11] = new Edge(3, 16);
edges[12] = new Edge(4, 10);
edges[13] = new Edge(4, 14);
edges[14] = new Edge(4, 19);
edges[15] = new Edge(5, 11);
edges[16] = new Edge(5, 15);
edges[17] = new Edge(5, 19);
edges[18] = new Edge(6, 11);
edges[19] = new Edge(6, 13);
edges[20] = new Edge(6, 18);
edges[21] = new Edge(7, 10);
edges[22] = new Edge(7, 12);
edges[23] = new Edge(7, 18);
edges[24] = new Edge(8, 10);
edges[25] = new Edge(9, 11);
edges[26] = new Edge(12, 13);
edges[27] = new Edge(14, 15);
edges[28] = new Edge(16, 17);
edges[29] = new Edge(18, 19);
Face[] faces = new Face[12];
faces[0] = new Face(5, new int[] { 0, 14, 15, 1, 17 });
faces[1] = new Face(5, new int[] { 1, 15, 5, 11, 9 });
faces[2] = new Face(5, new int[] { 1, 9, 2, 16, 17 });
faces[3] = new Face(5, new int[] { 2, 9, 11, 6, 13 });
faces[4] = new Face(5, new int[] { 0, 17, 16, 3, 8 });
faces[5] = new Face(5, new int[] { 2, 13, 12, 3, 16 });
faces[6] = new Face(5, new int[] { 0, 8, 10, 4, 14 });
faces[7] = new Face(5, new int[] { 3, 12, 7, 10, 8 });
faces[8] = new Face(5, new int[] { 4, 10, 7, 18, 19 });
faces[9] = new Face(5, new int[] { 4, 19, 5, 15, 14 });
faces[10] = new Face(5, new int[] { 6, 18, 7, 12, 13 });
faces[11] = new Face(5, new int[] { 5, 19, 18, 6, 11 });
return new ConvexPolyhedron(20, 30, 12, vertices, edges, faces);
}
/// <summary>
/// Creates Rhombic dodecahedron
/// </summary>
public static ConvexPolyhedron RhombicDodecahedron()
{
Point3d[] vertices = new Point3d[14];
vertices[0] = new Point3d(-1, -1, -1);
vertices[1] = new Point3d(1, -1, -1);
vertices[2] = new Point3d(1, 1, -1);
vertices[3] = new Point3d(-1, 1, -1);
vertices[4] = new Point3d(-1, -1, 1);
vertices[5] = new Point3d(1, -1, 1);
vertices[6] = new Point3d(1, 1, 1);
vertices[7] = new Point3d(-1, 1, 1);
vertices[8] = new Point3d(0, -2, 0);
vertices[9] = new Point3d(2, 0, 0);
vertices[10] = new Point3d(0, 2, 0);
vertices[11] = new Point3d(-2, 0, 0);
vertices[12] = new Point3d(0, 0, -2);
vertices[13] = new Point3d(0, 0, 2);
Edge[] edges = new Edge[24];
edges[0] = new Edge(0, 8);
edges[1] = new Edge(1, 8);
edges[2] = new Edge(4, 8);
edges[3] = new Edge(5, 8);
edges[4] = new Edge(1, 9);
edges[5] = new Edge(2, 9);
edges[6] = new Edge(5, 9);
edges[7] = new Edge(6, 9);
edges[8] = new Edge(2, 10);
edges[9] = new Edge(3, 10);
edges[10] = new Edge(6, 10);
edges[11] = new Edge(7, 10);
edges[12] = new Edge(0, 11);
edges[13] = new Edge(3, 11);
edges[14] = new Edge(4, 11);
edges[15] = new Edge(7, 11);
edges[16] = new Edge(0, 12);
edges[17] = new Edge(1, 12);
edges[18] = new Edge(2, 12);
edges[19] = new Edge(3, 12);
edges[20] = new Edge(4, 13);
edges[21] = new Edge(5, 13);
edges[22] = new Edge(6, 13);
edges[23] = new Edge(7, 13);
Face[] faces = new Face[12];
faces[0] = new Face(4, new int[] { 0, 12, 1, 8 });
faces[1] = new Face(4, new int[] { 1, 12, 2, 9 });
faces[2] = new Face(4, new int[] { 2, 12, 3, 10 });
faces[3] = new Face(4, new int[] { 3, 12, 0, 11 });
faces[4] = new Face(4, new int[] { 4, 8, 5, 13 });
faces[5] = new Face(4, new int[] { 5, 9, 6, 13 });
faces[6] = new Face(4, new int[] { 6, 10, 7, 13 });
faces[7] = new Face(4, new int[] { 7, 11, 4, 13 });
faces[8] = new Face(4, new int[] { 0, 8, 4, 11 });
faces[9] = new Face(4, new int[] { 1, 9, 5, 8 });
faces[10] = new Face(4, new int[] { 2, 10, 6, 9 });
faces[11] = new Face(4, new int[] { 3, 11, 7, 10 });
return new ConvexPolyhedron(14, 24, 12, vertices, edges, faces);
}
/// <summary>
/// Creates Cuboctahedron
/// </summary>
public static ConvexPolyhedron Cuboctahedron()
{
Point3d[] vertices = new Point3d[12];
vertices[0] = new Point3d(0, -0.5, -0.5);
vertices[1] = new Point3d(0.5, 0, -0.5);
vertices[2] = new Point3d(0, 0.5, -0.5);
vertices[3] = new Point3d(-0.5, 0, -0.5);
vertices[4] = new Point3d(0, -0.5, 0.5);
vertices[5] = new Point3d(0.5, 0, 0.5);
vertices[6] = new Point3d(0, 0.5, 0.5);
vertices[7] = new Point3d(-0.5, 0, 0.5);
vertices[8] = new Point3d(-0.5, -0.5, 0);
vertices[9] = new Point3d(0.5, -0.5, 0);
vertices[10] = new Point3d(0.5, 0.5, 0);
vertices[11] = new Point3d(-0.5, 0.5, 0);
Edge[] edges = new Edge[24];
edges[0] = new Edge(0, 1);
edges[1] = new Edge(1, 2);
edges[2] = new Edge(2, 3);
edges[3] = new Edge(3, 0);
edges[4] = new Edge(4, 5);
edges[5] = new Edge(5, 6);
edges[6] = new Edge(6, 7);
edges[7] = new Edge(7, 4);
edges[8] = new Edge(0, 9);
edges[9] = new Edge(9, 4);
edges[10] = new Edge(4, 8);
edges[11] = new Edge(8, 0);
edges[12] = new Edge(1, 10);
edges[13] = new Edge(10, 5);
edges[14] = new Edge(5, 9);
edges[15] = new Edge(9, 1);
edges[16] = new Edge(2, 11);
edges[17] = new Edge(11, 6);
edges[18] = new Edge(6, 10);
edges[19] = new Edge(10, 2);
edges[20] = new Edge(3, 8);
edges[21] = new Edge(8, 7);
edges[22] = new Edge(7, 11);
edges[23] = new Edge(11, 3);
Face[] faces = new Face[14];
faces[0] = new Face(4, new int[] { 0, 3, 2, 1 });
faces[1] = new Face(4, new int[] { 4, 5, 6, 7 });
faces[2] = new Face(4, new int[] { 0, 9, 4, 8 });
faces[3] = new Face(4, new int[] { 1, 10, 5, 9 });
faces[4] = new Face(4, new int[] { 2, 11, 6, 10 });
faces[5] = new Face(4, new int[] { 3, 8, 7, 11 });
faces[6] = new Face(3, new int[] { 0, 1, 9 });
faces[7] = new Face(3, new int[] { 1, 2, 10 });
faces[8] = new Face(3, new int[] { 2, 3, 11 });
faces[9] = new Face(3, new int[] { 3, 0, 8 });
faces[10] = new Face(3, new int[] { 9, 5, 4 });
faces[11] = new Face(3, new int[] { 10, 6, 5 });
faces[12] = new Face(3, new int[] { 11, 7, 6 });
faces[13] = new Face(3, new int[] { 8, 4, 7 });
return new ConvexPolyhedron(12, 24, 14, vertices, edges, faces);
}
/// <summary>
/// Creates Rhombicuboctahedron
/// </summary>
public static ConvexPolyhedron Rhombicuboctahedron(double delta)
{
delta = delta / 2;
Point3d[] vertices = new Point3d[24];
vertices[0] = new Point3d(-0.5 + delta, -0.5 + delta, -0.5);
vertices[1] = new Point3d(0.5 - delta, -0.5 + delta, -0.5);
vertices[2] = new Point3d(0.5 - delta, 0.5 - delta, -0.5);
vertices[3] = new Point3d(-0.5 + delta, 0.5 - delta, -0.5);
vertices[4] = new Point3d(-0.5 + delta, -0.5 + delta, 0.5);
vertices[5] = new Point3d(0.5 - delta, -0.5 + delta, 0.5);
vertices[6] = new Point3d(0.5 - delta, 0.5 - delta, 0.5);
vertices[7] = new Point3d(-0.5 + delta, 0.5 - delta, 0.5);
vertices[8] = new Point3d(-0.5 + delta, -0.5, -0.5 + delta);
vertices[9] = new Point3d(0.5 - delta, -0.5, -0.5 + delta);
vertices[10] = new Point3d(0.5 - delta, -0.5, 0.5 - delta);
vertices[11] = new Point3d(-0.5 + delta, -0.5, 0.5 - delta);
vertices[12] = new Point3d(0.5, -0.5 + delta, -0.5 + delta);
vertices[13] = new Point3d(0.5, 0.5 - delta, -0.5 + delta);
vertices[14] = new Point3d(0.5, 0.5 - delta, 0.5 - delta);
vertices[15] = new Point3d(0.5, -0.5 + delta, 0.5 - delta);
vertices[16] = new Point3d(-0.5 + delta, 0.5, -0.5 + delta);
vertices[17] = new Point3d(0.5 - delta, 0.5, -0.5 + delta);
vertices[18] = new Point3d(0.5 - delta, 0.5, 0.5 - delta);
vertices[19] = new Point3d(-0.5 + delta, 0.5, 0.5 - delta);
vertices[20] = new Point3d(-0.5, -0.5 + delta, -0.5 + delta);
vertices[21] = new Point3d(-0.5, 0.5 - delta, -0.5 + delta);
vertices[22] = new Point3d(-0.5, 0.5 - delta, 0.5 - delta);
vertices[23] = new Point3d(-0.5, -0.5 + delta, 0.5 - delta);
Edge[] edges = new Edge[48];
edges[0] = new Edge(0, 1);
edges[1] = new Edge(1, 2);
edges[2] = new Edge(2, 3);
edges[3] = new Edge(3, 0);
edges[4] = new Edge(4, 5);
edges[5] = new Edge(5, 6);
edges[6] = new Edge(6, 7);
edges[7] = new Edge(7, 4);
edges[8] = new Edge(8, 9);
edges[9] = new Edge(9, 10);
edges[10] = new Edge(10, 11);
edges[11] = new Edge(11, 8);
edges[12] = new Edge(12, 13);
edges[13] = new Edge(13, 14);
edges[14] = new Edge(14, 15);
edges[15] = new Edge(15, 12);
edges[16] = new Edge(16, 17);
edges[17] = new Edge(17, 18);
edges[18] = new Edge(18, 19);
edges[19] = new Edge(19, 16);
edges[20] = new Edge(20, 21);
edges[21] = new Edge(21, 22);
edges[22] = new Edge(22, 23);
edges[23] = new Edge(23, 20);
edges[24] = new Edge(1, 12);
edges[25] = new Edge(12, 9);
edges[26] = new Edge(9, 1);
edges[27] = new Edge(2, 17);
edges[28] = new Edge(17, 13);
edges[29] = new Edge(13, 2);
edges[30] = new Edge(3, 16);
edges[31] = new Edge(16, 21);
edges[32] = new Edge(21, 3);
edges[33] = new Edge(0, 8);
edges[34] = new Edge(8, 20);
edges[35] = new Edge(20, 0);
edges[36] = new Edge(5, 10);
edges[37] = new Edge(10, 15);
edges[38] = new Edge(15, 5);
edges[39] = new Edge(6, 14);
edges[40] = new Edge(14, 18);
edges[41] = new Edge(18, 6);
edges[42] = new Edge(7, 22);
edges[43] = new Edge(22, 19);
edges[44] = new Edge(19, 7);
edges[45] = new Edge(4, 23);
edges[46] = new Edge(23, 11);
edges[47] = new Edge(11, 4);
Face[] faces = new Face[26];
faces[0] = new Face(4, new int[] { 0, 3, 2, 1 });
faces[1] = new Face(4, new int[] { 4, 5, 6, 7 });
faces[2] = new Face(4, new int[] { 8, 9, 10, 11 });
faces[3] = new Face(4, new int[] { 12, 13, 14, 15 });
faces[4] = new Face(4, new int[] { 17, 16, 19, 18 });
faces[5] = new Face(4, new int[] { 21, 20, 23, 22 });
faces[6] = new Face(4, new int[] { 0, 1, 9, 8 });
faces[7] = new Face(4, new int[] { 1, 2, 13, 12 });
faces[8] = new Face(4, new int[] { 2, 3, 16, 17 });
faces[9] = new Face(4, new int[] { 0, 20, 21, 3 });
faces[10] = new Face(4, new int[] { 11, 10, 5, 4 });
faces[11] = new Face(4, new int[] { 15, 14, 6, 5 });
faces[12] = new Face(4, new int[] { 18, 19, 7, 6 });
faces[13] = new Face(4, new int[] { 22, 23, 4, 7 });
faces[14] = new Face(4, new int[] { 9, 12, 15, 10 });
faces[15] = new Face(4, new int[] { 13, 17, 18, 14 });
faces[16] = new Face(4, new int[] { 16, 21, 22, 19 });
faces[17] = new Face(4, new int[] { 20, 8, 11, 23 });
faces[18] = new Face(3, new int[] { 0, 8, 20 });
faces[19] = new Face(3, new int[] { 1, 12, 9 });
faces[20] = new Face(3, new int[] { 2, 17, 13 });
faces[21] = new Face(3, new int[] { 3, 21, 16 });
faces[22] = new Face(3, new int[] { 4, 23, 11 });
faces[23] = new Face(3, new int[] { 5, 10, 15 });
faces[24] = new Face(3, new int[] { 6, 14, 18 });
faces[25] = new Face(3, new int[] { 7, 19, 22 });
return new ConvexPolyhedron(24, 48, 26, vertices, edges, faces);
}
#endregion
#region "Properties"
/// <summary>
/// Center of mass.
/// </summary>
public Point3d Center
{
get
{
Point3d center = new Point3d(); ;
foreach (Point3d p in vertex)
{
center += p;
}
return center / vertex.Length;
}
}
/// <summary>
/// Volume of the polyhedron.
/// </summary>
public double Volume
{
get
{
double volume = 0;
foreach (Face f in face)
{
for (int i = 0; i < f.vertex.Length - 2; i++)
{
Vector3d v1 = new Vector3d(this.vertex[0], f.Vertex[0]);
Vector3d v2 = new Vector3d(this.vertex[0], f.Vertex[i + 1]);
Vector3d v3 = new Vector3d(this.vertex[0], f.Vertex[i + 2]);
volume += v1 * (v2.Cross(v3));
}
}
return volume / 6;
}
}
/// <summary>
/// Surface area of the polyhedron.
/// </summary>
public double Area
{
get
{
double area = 0;
foreach (Face f in face)
{
area += f.Area;
}
return area;
}
}
/// <summary>
/// List of edges forming the polyhedron
/// </summary>
public List<Segment3d> ListOfEdges
{
get
{
lock (this)
{
if (_list_e == null)
{
_list_e = new List<Segment3d> { };
foreach (Edge e in edge)
{
_list_e.Add(new Segment3d(e.P1, e.P2));
}
return _list_e;
}
else
{
return _list_e;
}
}
}
}
#endregion
/// <summary>
/// Creates copy of the object
/// </summary>
public ConvexPolyhedron Copy()
{
Point3d[] vertex_copy = new Point3d[vertex.Length];
Edge[] edge_copy = new Edge[edge.Length];
Face[] face_copy = new Face[face.Length];
Dictionary<Int32, Point3d> dict = new Dictionary<Int32, Point3d>();
for (int i = 0; i < vertex.Length; i++)
{
vertex_copy[i] = vertex[i].Copy();
}
for (int i = 0; i < edge.Length; i++)
{
edge_copy[i].p1 = edge[i].p1;
edge_copy[i].p2 = edge[i].p2;
}
for (int i = 0; i < face.Length; i++)
{
face_copy[i].normal = face[i].normal;
face_copy[i].numVertices = face[i].numVertices;
face_copy[i].vertex = new int[face[i].vertex.Length];
for (int j = 0; j < face[i].vertex.Length; j++)
{
face_copy[i].vertex[j] = face[i].vertex[j];
}
}
return new ConvexPolyhedron(numVertices, numEdges, numFaces, vertex_copy, edge_copy, face_copy);
}
private void CheckFaceOrientation()
{
for (int i = 0; i < face.Length; i++)
{
Vector3d normal = face[i].normal;
Vector3d to_center = new Vector3d(face[i].Vertex[0], this.Center);
if (to_center * normal > 0)
{
face[i] = ReverseFace(face[i]);
}
}
}
private Face ReverseFace(Face face)
{
int[] tmp = new int[face.numVertices];
for (int j = 0; j < face.numVertices; j++)
{
tmp[j] = face.vertex[face.numVertices - j - 1];
}
face.vertex = tmp;
face.UpdateNormal();
return face;
}
#region "BoundingBox"
/// <summary>
/// Return minimum bounding box.
/// </summary>
public Box3d MinimumBoundingBox
{
get
{
throw new NotImplementedException();
}
}
/// <summary>
/// Return Bounding Box in given coordinate system.
/// </summary>
public Box3d BoundingBox(Coord3d coord = null)
{
return Box3d.BoundingBox(vertex, coord);
}
/// <summary>
/// Return Axis Aligned Bounding Box (AABB).
/// </summary>
public AABB AABB()
{
if (_aabb == null)
{
_aabb = GeometRi.AABB.BoundingBox(vertex);
}
return _aabb;
}
/// <summary>
/// Return bounding sphere.
/// </summary>
public Sphere BoundingSphere
{
get
{
throw new NotImplementedException();
}
}
#endregion
#region "Distance"
/// <summary>
/// Distance from polyhedron to point (zero will be returned for point located inside polyhedron)
/// </summary>
public double DistanceTo(Point3d p)
{
if (p.BelongsTo(this))
{
return 0;
}
// test faces
for (int i = 0; i < numFaces; i++)
{
// test only visible faces
double point_face_plane_dist = face[i].normal * new Vector3d(face[i].Vertex[0], p);
if (point_face_plane_dist < 0)
{
continue;
}
Point3d projection_point = p - point_face_plane_dist * face[i].normal;
// test if projection of point is inside the face
bool inside = true;
for (int l = 0; l < this.face[i].vertex.Length; l++)
{
Vector3d edge = new Vector3d(this.face[i].Vertex[l], this.face[i].Vertex[0]);
if (l < this.face[i].vertex.Length - 1)
{
edge = new Vector3d(this.face[i].Vertex[l], this.face[i].Vertex[l + 1]);
}
Vector3d v = new Vector3d(this.face[i].Vertex[l], projection_point);
if (edge.Cross(v).Dot(this.face[i].normal) < 0)
{
// projection outside of face
inside = false;
break;
}
}
if (inside)
{
return point_face_plane_dist;
}
}
// test edges
double dist = double.PositiveInfinity;
foreach (Segment3d s1 in ListOfEdges)
{
double tmp_dist = p.DistanceTo(s1);
if (tmp_dist < dist)
{
dist = tmp_dist;
}
}
return dist;
}
/// <summary>
/// Distance from polyhedron to circle (zero will be returned for circle located inside polyhedron)
/// </summary>
public double DistanceTo(Circle3d c)
{
if (c._point.BelongsTo(this))
{
return 0;
}
double dist = double.PositiveInfinity;
for (int i = 0; i < numFaces; i++)
{
// test only visible faces
if (face[i].normal * new Vector3d(face[i].Vertex[0], c._point) < 0)
{
continue;
}
for (int j = 0; j < face[i].vertex.Length - 2; j++)
{
Triangle t = new Triangle(face[i].Vertex[0], face[i].Vertex[j + 1], face[i].Vertex[j + 2]);
double tmp_dist = t.DistanceTo(c);
if (tmp_dist <= GeometRi3D.Tolerance)
{
return tmp_dist;
}
if (tmp_dist < dist)
{
dist = tmp_dist;
}
}
}
return dist;
}
/// <summary>
/// Distance from polyhedron to sphere
/// </summary>
public double DistanceTo(Sphere s)
{
double dist = this.DistanceTo(s.Center) - s.R;
return dist < 0 ? 0 : dist;
}
/// <summary>
/// Distance between two polyhedrons
/// </summary>
/// <param name="c">Target polyhedron</param>
public double DistanceTo(ConvexPolyhedron c)
{
// Use "Method of Separating Axes" to test intersection combined with distance calculation
// Intersection of Convex Objects: The Method of Separating Axes
// David Eberly, Geometric Tools, Redmond WA 98052
// Creative Commons Attribution 4.0 International License
double dist = double.PositiveInfinity;
bool intersecting = true;
// Test faces of this CP for separation. Because of the counterclockwise ordering,
// the projection interval for this CP is (-inf, 0].
// Determine whether 'c' is on the positive side of the line
for (int i = 0; i < this.numFaces; i++)
{
Vector3d N = this.face[i].normal;
if (WhichSide(c.vertex, this.face[i].Vertex[0], N) > 0)
{
// 'c' is entirely on the positive side of the line P + t * N
// Calculate min projection distance to face's plane
intersecting = false;
double square_proj_dist = double.PositiveInfinity;
Point3d best_proj_point = this.face[i].Vertex[0];
Point3d target_point = this.face[i].Vertex[0];
Plane3d plane = new Plane3d(this.face[i].Vertex[0], this.face[i].normal);
foreach (Point3d point in c.vertex)
{
Point3d projection = point.ProjectionTo(plane);
double tmp_dist = projection.DistanceSquared(point);
if (tmp_dist < square_proj_dist)
{
square_proj_dist = tmp_dist;
best_proj_point = projection;
target_point = point;
}
}
// test if best projection of c.vertex is inside the face
bool inside = true;
for (int l = 0; l < this.face[i].vertex.Length; l++)
{
Vector3d edge = new Vector3d(this.face[i].Vertex[l], this.face[i].Vertex[0]);
if (l < this.face[i].vertex.Length - 1)
{
edge = new Vector3d(this.face[i].Vertex[l], this.face[i].Vertex[l + 1]);
}
Vector3d v = new Vector3d(this.face[i].Vertex[l], best_proj_point);
if (edge.Cross(v).Dot(this.face[i].normal) < 0)
{
// projection outside of face
inside = false;
break;
}
}
if (inside)
{
double tmp_dist = Math.Sqrt(square_proj_dist);
if (tmp_dist < dist)
{
dist = tmp_dist;
return dist;
}
}
}
}
// Test faces 'c' for separation. Because of the counterclockwise ordering,
// the projection interval for 'c' is (-inf, 0].
// Determine whether this CP is on the positive side of the line
for (int i = 0; i < c.numFaces; i++)
{
Vector3d N = c.face[i].normal;
if (WhichSide(this.vertex, c.face[i].Vertex[0], N) > 0)
{
// this CP is entirely on the positive side of the line P + t * N
// Calculate min projection distance to face's plane
intersecting = false;
double square_proj_dist = double.PositiveInfinity;
Point3d best_proj_point = c.face[i].Vertex[0];
Point3d target_point = c.face[i].Vertex[0];
Plane3d plane = new Plane3d(c.face[i].Vertex[0], c.face[i].normal);
foreach (Point3d point in this.vertex)
{
Point3d projection = point.ProjectionTo(plane);
double tmp_dist = projection.DistanceSquared(point);
if (tmp_dist < square_proj_dist)
{
square_proj_dist = tmp_dist;
best_proj_point = projection;
target_point = point;
}
}
// test if best projection of this.vertex is inside the face
bool inside = true;
for (int l = 0; l < c.face[i].vertex.Length; l++)
{
Vector3d edge = new Vector3d(c.face[i].Vertex[l], c.face[i].Vertex[0]);
if (l < c.face[i].vertex.Length - 1)
{
edge = new Vector3d(c.face[i].Vertex[l], c.face[i].Vertex[l + 1]);
gitextract_h_mvhxyk/ ├── .gitattributes ├── .gitignore ├── GeometRi/ │ ├── AABB.cs │ ├── AbstractClass.cs │ ├── Box3d.cs │ ├── Circle3D.cs │ ├── ConvexPolyhedron.cs │ ├── Coord3D.cs │ ├── Ellipse.cs │ ├── Ellipsoid.cs │ ├── GeometRi.csproj │ ├── GeometRi3D.cs │ ├── Interface.cs │ ├── Line3D.cs │ ├── Matrix3D.cs │ ├── Plane3D.cs │ ├── Point3D.cs │ ├── Quaternion.cs │ ├── Ray3D.cs │ ├── Rotation.cs │ ├── Segment3D.cs │ ├── Sphere.cs │ ├── Tetrahedron.cs │ ├── Triangle.cs │ └── Vector3D.cs ├── GeometRi.Benchmarks/ │ ├── GeometRi.Benchmarks.csproj │ ├── Program.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ └── app.config ├── GeometRi.Example/ │ ├── GeometRi.Example.csproj │ ├── Program.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ └── app.config ├── GeometRi.Example.FSharp/ │ ├── App.config │ ├── AssemblyInfo.fs │ ├── GeometRi.Example.FSharp.fsproj │ ├── Program.fs │ └── packages.config ├── GeometRi.Tests/ │ ├── AABBTest.cs │ ├── BoundingBoxTest.cs │ ├── Box3dTest.cs │ ├── CircleTest.cs │ ├── ConvexPolyhedronTest.cs │ ├── CoordTransformTest.cs │ ├── CoplanarityTest.cs │ ├── EllipseTest.cs │ ├── EllipsoidTest.cs │ ├── GeometRi.Tests.csproj │ ├── Line3DTest.cs │ ├── Matrix3dTest.cs │ ├── NormalizeTest.cs │ ├── OtherTest.cs │ ├── Plane3dTest.cs │ ├── Point3DTest.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── QuaternionTest.cs │ ├── Ray3DTest.cs │ ├── ReflectTest.cs │ ├── RelativeToleranceTest.cs │ ├── RotateTest.cs │ ├── RotationTest.cs │ ├── Segment3dTest.cs │ ├── SphereTest.cs │ ├── TetrahedronTest.cs │ ├── TranslateTest.cs │ ├── TriangleIntersectionWithLineSegmentTests.cs │ ├── TriangleTest.cs │ ├── Vector3dTest.cs │ └── packages.config ├── GeometRi.sln ├── LICENSE.txt ├── README.md ├── ReleaseNotes.md └── ToDo.txt
SYMBOL INDEX (1231 symbols across 52 files)
FILE: GeometRi.Benchmarks/Program.cs
class IntersectionBenchmark (line 8) | class IntersectionBenchmark
method Main (line 10) | static void Main(string[] args)
method Profile (line 130) | static void Profile(string description, int iterations, Action action)
method TestPointTriangleDistance (line 160) | static void TestPointTriangleDistance()
method TestSegmentTriangleDistance (line 198) | static void TestSegmentTriangleDistance()
method TestSegmentPolyhedronDistance (line 226) | static void TestSegmentPolyhedronDistance()
method TestTrianglePolyhedronDistance (line 255) | static void TestTrianglePolyhedronDistance()
FILE: GeometRi.Example/Program.cs
class Program (line 8) | class Program
method Main (line 10) | public static void Main()
FILE: GeometRi.Tests/AABBTest.cs
class AABBTest (line 8) | [TestClass]
method AABB_DistanceTo_AABB_1 (line 11) | [TestMethod]
method AABB_DistanceTo_AABB_2 (line 20) | [TestMethod]
method AABB_IntersectionWith_AABB_01 (line 29) | [TestMethod]
method AABB_IntersectionWith_AABB_02 (line 43) | [TestMethod]
method AABB_IntersectionWith_AABB_03 (line 58) | [TestMethod]
method PointInAABBTest (line 71) | [TestMethod]
FILE: GeometRi.Tests/BoundingBoxTest.cs
class BoundingBoxTest (line 8) | [TestClass]
method EllipsoidAABBTest (line 11) | [TestMethod]
method SphereAABBTest (line 43) | [TestMethod]
method TriangleAABBTest (line 72) | [TestMethod]
method CircleAABBTest (line 85) | [TestMethod]
FILE: GeometRi.Tests/Box3dTest.cs
class Box3dTest (line 9) | [TestClass]
method DefaultBoxTest (line 12) | [TestMethod]
method CornerPointsTest (line 24) | [TestMethod]
method BoxOrientationTest (line 42) | [TestMethod]
method PointInAlignedBoxTest (line 55) | [TestMethod]
method PointInAlignedBoxRelativeTest (line 86) | [TestMethod]
method ClosestPointTest (line 126) | [TestMethod]
method DistanceToPointTest (line 147) | [TestMethod]
method LineIntersectionWithBoxTest (line 160) | [TestMethod]
method RayIntersectionWithBoxTest (line 192) | [TestMethod]
method SegmentIntersectionWithBoxTest (line 228) | [TestMethod]
method SegmentIntersectionWithBoxRelativeTest (line 258) | [TestMethod]
method BoxRotationTest (line 319) | [TestMethod]
method BoxReflectInPointTest (line 335) | [TestMethod]
method BoxReflectInLineTest (line 363) | [TestMethod]
method BoxReflectInPlaneTest (line 391) | [TestMethod]
method BoxDistanceToCircleTest (line 419) | [TestMethod()]
method BoxIntersectsCircleTest (line 430) | [TestMethod()]
method BoxIntersectsCircleTest2 (line 448) | [TestMethod()]
method BoxIntersectsTriangleTest (line 460) | [TestMethod()]
method BoxIntersectsBoxTest_01 (line 482) | [TestMethod()]
method BoxIntersectsBoxTest_02 (line 491) | [TestMethod()]
method BoxIntersectsBoxTest_03 (line 500) | [TestMethod()]
FILE: GeometRi.Tests/CircleTest.cs
class CircleTest (line 8) | [TestClass]
method CircleBy3PointsTest (line 15) | [TestMethod()]
method CircleIntersectionWithLineTest (line 28) | [TestMethod()]
method CircleIntersectionWithRayTest (line 58) | [TestMethod()]
method CircleIntersectionWithPlaneTest (line 72) | [TestMethod()]
method CircleIntersectionWithCircle2DTest (line 101) | [TestMethod()]
method CircleIntersectionWithCircle3DTest (line 143) | [TestMethod()]
method CircleIntersectionWithCircle3DTest_2 (line 189) | [TestMethod()]
method CircleIntersectionWithCircle3DTest_3 (line 209) | [TestMethod()]
method CircleIntersectionWithCircle3DTest_4 (line 229) | [TestMethod()]
method CircleIntersectionWithCircle3DTest_5 (line 249) | [TestMethod()]
method CircleIntersectionWithCircle3DTest_6 (line 269) | [TestMethod()]
method CircleIntersectionWithCircle3DTest_7 (line 282) | [TestMethod()]
method CircleDistanceToPlaneTest (line 293) | [TestMethod()]
method CircleDistanceToPointTest (line 310) | [TestMethod()]
method CircleDistanceToCircleTest (line 327) | [TestMethod()]
method CircleDistanceToCircleTest_02 (line 338) | [TestMethod()]
method CircleDistanceToCircleGreaterTest (line 349) | [TestMethod()]
method CircleToCircleClosestPointTest (line 374) | [TestMethod()]
method CircleParametricFormTest (line 423) | [TestMethod()]
method CircleToEllipseTest (line 430) | [TestMethod()]
method CircleProjectionToPlaneTest (line 445) | [TestMethod()]
method PointInCircleTest (line 460) | [TestMethod]
method PointInCircleRelativeTest (line 491) | [TestMethod]
method IsInsideBoxTest (line 531) | [TestMethod()]
method CircleIntersectsSphereTest (line 543) | [TestMethod()]
method CircleDistanceToSphereTest (line 572) | [TestMethod()]
method CircleDistanceToLineTest (line 616) | [TestMethod()]
method CircleClosestPointToPlaneTest (line 666) | [TestMethod()]
method CircleClosestPointToTriangleTest (line 688) | [TestMethod()]
method CircleBoundaryDistanceToLineTest (line 729) | [TestMethod()]
FILE: GeometRi.Tests/ConvexPolyhedronTest.cs
class ConvexPolyhedronTest (line 8) | [TestClass]
method AreaVolumeTest (line 11) | [TestMethod]
method TetrahedronIntersectionCheckTest (line 24) | [TestMethod]
method ConvexPolyhedronIntersectionCheckTest_01 (line 73) | [TestMethod]
method ConvexPolyhedronIntersectionCheckTest_02 (line 90) | [TestMethod]
method ConvexPolyhedronIntersectionCheckTest_03 (line 111) | [TestMethod]
method ConvexPolyhedronIntersectionCheckTest_04 (line 132) | [TestMethod]
method TetrahedronDistanceTest (line 153) | [TestMethod]
method TetrahedronDistanceToTetrahedronTest_01 (line 208) | [TestMethod()]
method BoxIntersectionTest (line 238) | [TestMethod]
method OctahedronIntersectionCheckTest_03 (line 255) | [TestMethod]
method IcosahedronIntersectionCheckTest_03 (line 267) | [TestMethod]
method DodecaahedronIntersectionCheckTest_03 (line 279) | [TestMethod]
method CopyTest (line 293) | [TestMethod]
method BoxBoxDistanceTest_01 (line 302) | [TestMethod]
method BoxBoxDistanceTest_02 (line 314) | [TestMethod]
method BoxBoxDistanceTest_03 (line 329) | [TestMethod]
method BoxBoxDistanceTest_04 (line 344) | [TestMethod]
method BoxTetDistanceTest_04 (line 359) | [TestMethod]
method TetTetDistanceTest_01 (line 374) | [TestMethod]
method TetTetDistanceTest_02 (line 390) | [TestMethod]
method TetTetDistanceTest_03 (line 406) | [TestMethod]
method TetTetDistanceTest_04 (line 422) | [TestMethod]
method TetTetDistanceTest_05 (line 438) | [TestMethod]
method TetTetDistanceTest_06 (line 450) | [TestMethod]
method TetTetDistanceTest_07 (line 462) | [TestMethod]
method TetTetDistanceTest_08 (line 474) | [TestMethod]
method TetTetDistanceTest_09 (line 486) | [TestMethod]
method TetTetDistanceTest_10 (line 498) | [TestMethod]
method TetTetDistanceTest_11 (line 510) | [TestMethod]
method TetTetDistanceTest_12 (line 522) | [TestMethod]
method SegmentDistanceTest_01 (line 535) | [TestMethod]
method SegmentDistanceTest_02 (line 545) | [TestMethod]
method SegmentDistanceTest_03 (line 555) | [TestMethod]
method SegmentDistanceTest_04 (line 565) | [TestMethod]
method CircleDistanceTest_01 (line 576) | [TestMethod]
method ExtrudeTest_01 (line 585) | [TestMethod]
method ExtrudeTest_02 (line 593) | [TestMethod]
method PointDistanceTest_01 (line 602) | [TestMethod]
method PointDistanceTest_02 (line 612) | [TestMethod]
method PointDistanceTest_03 (line 627) | [TestMethod]
method PointDistanceTest_04 (line 642) | [TestMethod]
method PointDistanceTest_05 (line 651) | [TestMethod]
method PointDistanceTest_06 (line 663) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_01 (line 676) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_02 (line 686) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_03 (line 696) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_04 (line 706) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_05 (line 716) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_06 (line 726) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_07 (line 736) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_08 (line 746) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_09 (line 756) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_10 (line 771) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_11 (line 781) | [TestMethod]
method SegmentPolyhedronIntersectionCheckTest_12 (line 791) | [TestMethod]
method TrianglePolyhedronIntersectionCheckTest_01 (line 804) | [TestMethod]
method TrianglePolyhedronIntersectionCheckTest_02 (line 814) | [TestMethod]
method TrianglePolyhedronIntersectionCheckTest_03 (line 824) | [TestMethod]
method TrianglePolyhedronIntersectionCheckTest_04 (line 834) | [TestMethod]
method TrianglePolyhedronIntersectionCheckTest_05 (line 844) | [TestMethod]
FILE: GeometRi.Tests/CoordTransformTest.cs
class CoordTransformTest (line 8) | [TestClass]
method PointConvertToTest (line 15) | [TestMethod()]
method PointConvertToTest2 (line 25) | [TestMethod()]
method PointConvertToGlobalTest (line 37) | [TestMethod()]
method VectorConvertToTest (line 52) | [TestMethod()]
method VectorConvertToTest2 (line 62) | [TestMethod()]
method LineConvertToTest (line 76) | [TestMethod()]
method PlaneConvertToTest (line 93) | [TestMethod()]
method LineConvertProjectionToPlaneTest (line 110) | [TestMethod()]
method LineConvertProjectionToPlaneTest2 (line 127) | [TestMethod()]
method PlaneConvertIntersectionToPlaneTest (line 144) | [TestMethod()]
method PlaneConvertToGlobalTest (line 161) | [TestMethod()]
method PlaneIntersectionWithPlanesTest (line 179) | [TestMethod()]
FILE: GeometRi.Tests/CoplanarityTest.cs
class CoplanarityTest (line 8) | [TestClass]
method PlanarObjectsCoplanarityTest (line 11) | [TestMethod]
method LinearObjectsCoplanarityTest (line 40) | [TestMethod]
method PlanarLinearObjectsCoplanarityTest (line 65) | [TestMethod]
FILE: GeometRi.Tests/EllipseTest.cs
class EllipseTest (line 8) | [TestClass]
method PointBelongsToEllipseTest (line 15) | [TestMethod()]
method EllipseProjectionToPlaneTest (line 24) | [TestMethod()]
method EllipseIntersectionWithLineTest (line 40) | [TestMethod()]
method EllipseIntersectionWithPlaneTest (line 56) | [TestMethod()]
method PointInEllipseTest (line 72) | [TestMethod]
method PointInEllipseRelativeTest (line 103) | [TestMethod]
method ClosestPointTest (line 143) | [TestMethod()]
FILE: GeometRi.Tests/EllipsoidTest.cs
class EllipsoidTest (line 8) | [TestClass]
method EllipsoidIntersectionWithLineTest (line 11) | [TestMethod()]
method EllipsoidIntersectionWithSegmentRelativeTest (line 42) | [TestMethod()]
method EllipsoidIntersectionWithPlaneTest (line 70) | [TestMethod()]
method EllipsoidProjectionToLineTest_1 (line 94) | [TestMethod()]
method EllipsoidProjectionToLineTest_2 (line 113) | [TestMethod()]
method PointInEllipsoidTest (line 150) | [TestMethod]
method ClosestPointTest (line 175) | [TestMethod()]
method IntersectsEllipsoidSphere_01 (line 224) | [TestMethod()]
method IntersectsEllipsoidSphere_02 (line 242) | [TestMethod()]
method IntersectsEllipsoidSphere_03 (line 260) | [TestMethod()]
FILE: GeometRi.Tests/Line3DTest.cs
class Line3dTest (line 8) | [TestClass]
method LineDistanceToCrossingLineTest (line 15) | [TestMethod()]
method LineDistanceToParallelLineTest (line 28) | [TestMethod()]
method LinePerpendicularToLineTest (line 40) | [TestMethod()]
method LineIntersectionWithLineTest (line 54) | [TestMethod()]
method LineIntersectionWithPlaneTest (line 69) | [TestMethod()]
method LineIntersectionWithPlaneTest2 (line 80) | [TestMethod()]
method LineIntersectionWithPlaneTest3 (line 94) | [TestMethod()]
method LineProjectionToPlaneTest (line 108) | [TestMethod()]
FILE: GeometRi.Tests/Matrix3dTest.cs
class Matrix3dTest (line 8) | [TestClass]
method MatrixDeterminantTest (line 15) | [TestMethod()]
method MatrixInverseTest (line 22) | [TestMethod()]
method RotationMatrixOrthogonalityTest (line 29) | [TestMethod()]
method MatrixMaxNormTest (line 36) | [TestMethod()]
FILE: GeometRi.Tests/NormalizeTest.cs
class TestHighNumberTolerances (line 8) | [TestClass]
method testTriangleIntersection (line 11) | [TestMethod]
method testCoplanar (line 37) | [TestMethod]
method SimpleAngleTest (line 67) | [TestMethod]
method SimpleAngleTest2 (line 82) | [TestMethod]
FILE: GeometRi.Tests/OtherTest.cs
class OtherTest (line 8) | [TestClass]
method ToleranceTest (line 15) | [TestMethod()]
method CoordSystemTest (line 27) | [TestMethod()]
method IsParallelToTest (line 38) | [TestMethod()]
method AngleToTest (line 56) | [TestMethod()]
FILE: GeometRi.Tests/Plane3dTest.cs
class Plane3dTest (line 8) | [TestClass]
method PlaneIntersectionWithLineTest (line 15) | [TestMethod()]
method PlaneIntersectionWithLineTest2 (line 27) | [TestMethod()]
method PlaneIntersectionWithLineTest3 (line 41) | [TestMethod()]
method PlaneIntersectionWithTwoPlanesTest1 (line 59) | [TestMethod()]
method PlaneIntersectionWithTwoPlanesTest2 (line 71) | [TestMethod()]
method PlaneIntersectionWithTwoPlanesTest3 (line 83) | [TestMethod()]
method PlaneIntersectionWithTwoPlanesTest4 (line 95) | [TestMethod()]
method PlaneIntersectionWithTwoPlanesTest5 (line 116) | [TestMethod()]
method PlaneIntersectionWithTwoPlanesTest6 (line 129) | [TestMethod()]
method PlaneIntersectionWithTwoPlanesTest (line 150) | [TestMethod()]
method PlaneEqualsToPlaneTest (line 161) | [TestMethod()]
method PlaneAngleToPlaneTest (line 175) | [TestMethod()]
method PlaneAngleToPlaneTest2 (line 189) | [TestMethod()]
FILE: GeometRi.Tests/Point3DTest.cs
class Point3dTest (line 8) | [TestClass]
method PointAddDivideTest (line 15) | [TestMethod()]
method PointScaleTest (line 23) | [TestMethod()]
method PointDistanceToPointTest (line 31) | [TestMethod()]
method PointDistanceToLineTest (line 39) | [TestMethod()]
method PointDistanceToPlaneTest (line 51) | [TestMethod()]
method PointDistanceToRayTest (line 60) | [TestMethod()]
method PointDistanceToSegmentTest (line 76) | [TestMethod()]
method PointProjectionToPlaneTest (line 97) | [TestMethod()]
method PointProjectionToLineTest (line 109) | [TestMethod()]
method PointProjectionToSphereTest (line 123) | [TestMethod()]
method PointBelongsToLineTest (line 137) | [TestMethod()]
method PointBelongsToPlaneTest (line 147) | [TestMethod()]
method PointBelongsToRayTest (line 174) | [TestMethod()]
method PointBelongsToSegmentTest (line 188) | [TestMethod()]
method PointEqualsNullTest (line 203) | [TestMethod()]
FILE: GeometRi.Tests/QuaternionTest.cs
class QuaternionTest (line 8) | [TestClass]
method IdentityMatrixTest (line 11) | [TestMethod]
method ZeroRotationTest (line 19) | [TestMethod]
FILE: GeometRi.Tests/Ray3DTest.cs
class Ray3dTest (line 8) | [TestClass]
method RayDistanceToCrossingLineTest (line 15) | [TestMethod()]
method RayDistanceToCrossingLineTest2 (line 23) | [TestMethod()]
method RayIntersectionWithPlaneTest (line 31) | [TestMethod()]
method RayIntersectionWithPlaneTest2 (line 39) | [TestMethod()]
method RayIntersectionWithLineTest (line 47) | [TestMethod()]
method RayIntersectionWithSegmentTest (line 64) | [TestMethod()]
method RayIntersectionWithRayTest (line 93) | [TestMethod()]
method RayProjectionToPlaneTest (line 119) | [TestMethod()]
method RayDistanceToRayTest (line 127) | [TestMethod()]
method RayDistanceToRayTest_02 (line 141) | [TestMethod()]
FILE: GeometRi.Tests/ReflectTest.cs
class ReflectTest (line 8) | [TestClass]
method PointReflectInPointTest (line 15) | [TestMethod()]
method PointReflectInLineTest (line 24) | [TestMethod()]
method PointReflectInPlaneTest (line 34) | [TestMethod()]
method LineReflectInPointTest (line 43) | [TestMethod()]
method PlaneReflectInPlaneTest (line 53) | [TestMethod()]
method LineReflectInLineTest (line 70) | [TestMethod()]
FILE: GeometRi.Tests/RelativeToleranceTest.cs
class RelativeToleranceTest (line 6) | [TestClass]
method Segment3dRelativeToleranceTest (line 9) | [TestMethod]
method SphereRelativeToleranceTest (line 23) | [TestMethod]
method Circle3dRelativeToleranceTest (line 37) | [TestMethod]
method Point3dRelativeToleranceTest (line 51) | [TestMethod]
method Vector3dRelativeToleranceTest (line 65) | [TestMethod]
method Vector3dIsParallelToRelativeToleranceTest (line 80) | [TestMethod]
method Vector3dIsOrthogonalToRelativeToleranceTest (line 94) | [TestMethod]
method Line3dRelativeToleranceTest (line 108) | [TestMethod]
FILE: GeometRi.Tests/RotateTest.cs
class RotateTest (line 8) | [TestClass]
method PointRotationTest (line 15) | [TestMethod()]
method PointRotationAroundPointTest (line 28) | [TestMethod()]
method PointRotationAroundPointTest2 (line 41) | [TestMethod()]
method VectorRotationTest (line 54) | [TestMethod()]
method LineRotationTest (line 67) | [TestMethod()]
method PlaneRotationTest (line 81) | [TestMethod()]
FILE: GeometRi.Tests/RotationTest.cs
class RotationTest (line 8) | [TestClass]
method RotationMatrixTest (line 11) | [TestMethod]
method InverseRotationTest (line 22) | [TestMethod]
method PI_RotationTest (line 38) | [TestMethod]
method AxisToFromQuaternionTest (line 54) | [TestMethod]
method RotationFromCoordTest (line 66) | [TestMethod]
method AxisToFromMatrixTest (line 77) | [TestMethod]
method QuaternionToFromMatrixTest (line 89) | [TestMethod]
method FromEulerAnglesTest (line 113) | [TestMethod]
method SLERPTest (line 133) | [TestMethod]
method ToEulerAnglesXYZTest (line 162) | [TestMethod]
method ToEulerAnglesXYXTest (line 231) | [TestMethod]
method ToEulerAnglesDegenerateTest (line 299) | [TestMethod]
FILE: GeometRi.Tests/Segment3dTest.cs
class Segment3dTest (line 8) | [TestClass]
method SegmentProjectionToLineTest (line 15) | [TestMethod()]
method SegmentProjectionToLineTest2 (line 23) | [TestMethod()]
method SegmentProjectionToPlaneTest (line 31) | [TestMethod()]
method SegmentIntersectionWithPlaneTest (line 39) | [TestMethod()]
method SegmentDistanceToPlaneTest (line 56) | [TestMethod()]
method SegmentDistanceToLineTest (line 73) | [TestMethod()]
method SegmentIntersectionWithLineTest (line 90) | [TestMethod()]
method SegmentIntersectionWithSegmentTest (line 110) | [TestMethod()]
method SegmentIntersectionWithSegmentRelativeTest (line 158) | [TestMethod()]
method SegmentIntersectionWithSegmentSymmetryTest (line 213) | [TestMethod()]
method SegmentBelongsToLineTest (line 241) | [TestMethod()]
method SegmentDistanceToSegmentTest (line 255) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest01 (line 275) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest02 (line 289) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest03 (line 303) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest04 (line 317) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest05 (line 331) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest06 (line 345) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest07 (line 364) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest08 (line 384) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest09 (line 403) | [TestMethod()]
method SegmentDistanceToSegmentClosestPointsTest10 (line 424) | [TestMethod()]
method SegmentDistanceToRayTest (line 444) | [TestMethod()]
method SegmentAngleToPlaneTest (line 466) | [TestMethod()]
method SegmentEqualsTest (line 475) | [TestMethod()]
method PointInSegmentTest (line 485) | [TestMethod]
method PointInSegmentRelativeTest (line 516) | [TestMethod]
method SegmentDistanceToCircleTest (line 556) | [TestMethod()]
method SegmentDistanceToCircleTest_02 (line 570) | [TestMethod()]
FILE: GeometRi.Tests/SphereTest.cs
class SphereTest (line 8) | [TestClass]
method SphereEqualTest (line 15) | [TestMethod()]
method SphereIntersectionWithLineTest (line 31) | [TestMethod()]
method SphereIntersectionWithSegmentRelativeTest (line 50) | [TestMethod()]
method SphereIntersectionWithRayTest (line 77) | [TestMethod()]
method SphereIntersectionWithPlaneTest (line 89) | [TestMethod()]
method SphereIntersectionWithSphereTest (line 99) | [TestMethod()]
method SphereProjectionToPlaneTest (line 112) | [TestMethod()]
method SphereProjectionToLineTest (line 122) | [TestMethod()]
method PointInSphereTest (line 132) | [TestMethod]
method PointInSphereRelativeTest (line 157) | [TestMethod]
method SphereInBoxTest (line 191) | [TestMethod]
method SphereDistanceToSphereTest (line 209) | [TestMethod()]
FILE: GeometRi.Tests/TetrahedronTest.cs
class TetrahedronTest (line 8) | [TestClass]
method TetrahedronBasicTest (line 15) | [TestMethod()]
method TetrahedronPointLocationTest (line 24) | [TestMethod()]
method TetrahedronClosestPointTest (line 61) | [TestMethod()]
method TetrahedronScaleTest (line 91) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_01 (line 101) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_02 (line 111) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_03 (line 121) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_04 (line 131) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_05 (line 141) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_06 (line 151) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_07 (line 162) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_08 (line 175) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_09 (line 188) | [TestMethod()]
method TetrahedronIntersectsTetrahedronTest_10 (line 201) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_01 (line 214) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_02 (line 224) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_03 (line 234) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_04 (line 244) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_05 (line 254) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_06 (line 264) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_07 (line 275) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_08 (line 288) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_09 (line 301) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_10 (line 314) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_11 (line 325) | [TestMethod()]
method TetrahedronDistanceToTetrahedronTest_12 (line 336) | [TestMethod()]
method TetrahedronAABBTest (line 361) | [TestMethod()]
method TetrahedronAABBTest_01 (line 374) | [TestMethod()]
FILE: GeometRi.Tests/TranslateTest.cs
class TranslateTest (line 8) | [TestClass]
method TranslatePointTest1 (line 15) | [TestMethod()]
method TranslatePointTest (line 28) | [TestMethod()]
method TranslatePlaneTest (line 50) | [TestMethod()]
FILE: GeometRi.Tests/TriangleIntersectionWithLineSegmentTests.cs
class TriangleIntersectionWithLineSegmentTests (line 8) | [TestClass]
method TriangleNone (line 13) | [TestMethod]
method TriangleStraight (line 27) | [TestMethod]
method TriangleSkewedTriangle (line 41) | [TestMethod]
method TriangleSkewedLine (line 55) | [TestMethod]
method TriangleSkewed (line 69) | [TestMethod]
method TriangleSegment (line 85) | [TestMethod]
method TriangleSegmentPartial (line 101) | [TestMethod]
method TriangleSegmentAB (line 117) | [TestMethod]
method TriangleSegmentCAMiddleOfAB_BC (line 135) | [TestMethod]
method TriangleSegmentCA (line 153) | [TestMethod]
FILE: GeometRi.Tests/TriangleTest.cs
class TriangleTest (line 8) | [TestClass]
method TriangleEqualTest (line 15) | [TestMethod()]
method TriangleAreaTest (line 31) | [TestMethod()]
method TriangleBisectorTest (line 42) | [TestMethod()]
method TriangleExternalBisectorTest (line 58) | [TestMethod()]
method TriangleIncenterTest (line 76) | [TestMethod()]
method TriangleOrthocenterTest (line 87) | [TestMethod()]
method TriangleCentroidTest (line 98) | [TestMethod()]
method TriangleCircumcenterTest (line 109) | [TestMethod()]
method TriangleGeometryTest (line 120) | [TestMethod()]
method PointInTriangleTest (line 141) | [TestMethod]
method PointInsideRelativeTest (line 174) | [TestMethod]
method PointOnBoundaryRelativeTest (line 204) | [TestMethod]
method PointOutsideRelativeTest (line 246) | [TestMethod]
method TriangleIntersectionWithLineTest (line 288) | [TestMethod()]
method TriangleIntersectionWithLineRelativeTest (line 326) | [TestMethod()]
method TriangleIntersectionWithPlaneTest (line 355) | [TestMethod()]
method TriangleIntersectionWithPlaneRelativeTest_01 (line 380) | [TestMethod()]
method TriangleIntersectionWithPlaneRelativeTest_02 (line 404) | [TestMethod()]
method TriangleIntersectionWithSegmentRelativeTest (line 429) | [TestMethod()]
method TriangleIntersectionWithRayTest (line 455) | [TestMethod()]
method PointInTriangleTest2 (line 483) | [TestMethod()]
method TriangleDistanceToCircleTest (line 521) | [TestMethod()]
method TriangleIntersectsCircleTest (line 536) | [TestMethod()]
method TriangleIntersectsTriangleTest (line 594) | [TestMethod()]
method TriangleClosestPointTest (line 647) | [TestMethod()]
method TriangleDistanceToPointTest_01 (line 662) | [TestMethod()]
method TriangleDistanceToPointTest_02 (line 681) | [TestMethod()]
method TriangleDistanceToSegmentTest_01 (line 695) | [TestMethod()]
method TriangleDistanceToSegmentTest_02 (line 711) | [TestMethod()]
method TriangleDistanceToSegmentTest_03 (line 727) | [TestMethod()]
method TriangleDistanceToSegmentTest_04 (line 743) | [TestMethod()]
method TriangleDistanceToSegmentTest_05 (line 759) | [TestMethod()]
method TriangleDistanceToSegmentTest_06 (line 775) | [TestMethod()]
method TriangleIntersectsSphereTest_01 (line 791) | [TestMethod()]
method TriangleDistanceToTriangleTest_01 (line 814) | [TestMethod()]
method TriangleDistanceToTriangleTest_02 (line 833) | [TestMethod()]
method PointDistanceToTriangleTest (line 852) | [TestMethod()]
method PointDistanceToTriangleTest_02 (line 868) | [TestMethod()]
method TriangleRayIntersectionTest (line 884) | [TestMethod()]
method TriangleSegmentIntersectMiddleOfAB_BC (line 932) | [TestMethod()]
FILE: GeometRi.Tests/Vector3dTest.cs
class Vector3dTest (line 8) | [TestClass]
method VectorAngleTest (line 15) | [TestMethod()]
method VectorAngleTest2 (line 24) | [TestMethod()]
method VectorAngleToPlaneTest (line 33) | [TestMethod()]
FILE: GeometRi/AABB.cs
class AABB (line 10) | #if NET20_OR_GREATER
method AABB (line 30) | public AABB(Point3d center, double lx, double ly, double lz)
method AABB (line 41) | public AABB()
method AABB (line 50) | public AABB(Point3d Pmin, Point3d Pmax)
method Copy (line 65) | public AABB Copy()
method BoundingBox (line 436) | public Box3d BoundingBox(Coord3d coord = null)
method BoundingBox (line 471) | public static AABB BoundingBox(IEnumerable<Point3d> points)
method Union (line 496) | public static AABB Union(AABB box1, AABB box2)
method IntersectionWith (line 514) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 523) | public object IntersectionWith(Ray3d r)
method IntersectionWith (line 532) | public object IntersectionWith(Segment3d s)
method Intersects (line 540) | public bool Intersects(Triangle t)
method Intersects (line 558) | public bool Intersects(Box3d box)
method Intersects (line 570) | public bool Intersects(AABB box)
method Intersects (line 582) | public bool Intersects(Circle3d c)
method IsInside (line 599) | public bool IsInside(Box3d box)
method IsInside (line 611) | public bool IsInside(AABB box)
method IntersectionWith (line 623) | public AABB IntersectionWith(AABB box)
method _line_intersection (line 672) | private object _line_intersection(Line3d l, double t0, double t1)
method LocalCoord (line 780) | public Coord3d LocalCoord()
method ClosestPoint (line 788) | public Point3d ClosestPoint(Point3d p)
method DistanceTo (line 801) | public double DistanceTo(Point3d p)
method DistanceTo (line 809) | public double DistanceTo(AABB box)
method DistanceTo (line 823) | public double DistanceTo(Sphere s)
method DistanceTo (line 833) | public double DistanceTo(Circle3d c)
method _PointLocation (line 851) | internal override int _PointLocation(Point3d p)
method Translate (line 889) | public AABB Translate(Vector3d v)
method ReflectIn (line 899) | public virtual AABB ReflectIn(Point3d p)
method Scale (line 908) | public virtual AABB Scale(double scale, Point3d scaling_center)
method Equals (line 920) | public override bool Equals(object obj)
method GetHashCode (line 951) | public override int GetHashCode()
method ToString (line 960) | public override string ToString()
method ToString (line 968) | public string ToString(Coord3d coord)
FILE: GeometRi/AbstractClass.cs
class FiniteObject (line 8) | #if NET20_OR_GREATER
method _PointLocation (line 13) | abstract internal int _PointLocation(Point3d p);
class PlanarFiniteObject (line 15) | #if NET20_OR_GREATER
class LinearFiniteObject (line 22) | #if NET20_OR_GREATER
FILE: GeometRi/Box3d.cs
class Box3d (line 10) | #if NET20_OR_GREATER
method Box3d (line 33) | public Box3d(Point3d center, double lx, double ly, double lz)
method Box3d (line 50) | public Box3d(Coord3d coord = null)
method Box3d (line 73) | public Box3d(Point3d center, double lx, double ly, double lz, Rotation r)
method Box3d (line 94) | public Box3d(Point3d center, double lx, double ly, double lz, Coord3d ...
method Box3d (line 112) | public Box3d(Point3d p_min, Point3d p_max)
method Copy (line 130) | public Box3d Copy()
method BoundingBox (line 540) | public Box3d BoundingBox(Coord3d coord = null)
method BoundingBox (line 575) | public static Box3d BoundingBox(IEnumerable<Point3d> points, Coord3d c...
method IntersectionWith (line 606) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 615) | public object IntersectionWith(Ray3d r)
method IntersectionWith (line 624) | public object IntersectionWith(Segment3d s)
method Intersects (line 632) | public bool Intersects(Triangle t)
method Intersects (line 650) | public bool Intersects(Box3d box)
method _line_intersection (line 659) | private object _line_intersection(Line3d l, double t0, double t1)
method LocalCoord (line 767) | public Coord3d LocalCoord()
method ClosestPoint (line 775) | public Point3d ClosestPoint(Point3d p)
method AABBClosestPoint (line 789) | public Point3d AABBClosestPoint(Point3d p)
method DistanceTo (line 802) | public double DistanceTo(Point3d p)
method AABBDistanceTo (line 810) | public double AABBDistanceTo(Point3d p)
method DistanceTo (line 818) | public double DistanceTo(Sphere s)
method DistanceTo (line 828) | public double DistanceTo(Circle3d c)
method Intersects (line 847) | public bool Intersects(Circle3d c)
method _PointLocation (line 861) | internal override int _PointLocation(Point3d p)
method Translate (line 897) | public Box3d Translate(Vector3d v)
method Rotate (line 905) | public Box3d Rotate(Rotation r, Point3d p)
method ReflectIn (line 916) | public virtual Box3d ReflectIn(Point3d p)
method ReflectIn (line 926) | public virtual Box3d ReflectIn(Line3d l)
method ReflectIn (line 938) | public virtual Box3d ReflectIn(Plane3d s)
method Scale (line 951) | public virtual Box3d Scale(double scale, Point3d scaling_center)
method Equals (line 963) | public override bool Equals(object obj)
method GetHashCode (line 994) | public override int GetHashCode()
method ToString (line 1003) | public override string ToString()
method ToString (line 1011) | public string ToString(Coord3d coord)
FILE: GeometRi/Circle3D.cs
class Circle3d (line 11) | #if NET20_OR_GREATER
method Circle3d (line 24) | public Circle3d(Point3d Center, double Radius, Vector3d Normal)
method Circle3d (line 34) | public Circle3d(Point3d p1, Point3d p2, Point3d p3)
method Copy (line 66) | public Circle3d Copy()
method IsParallelTo (line 171) | public bool IsParallelTo(ILinearObject obj)
method IsNotParallelTo (line 179) | public bool IsNotParallelTo(ILinearObject obj)
method IsOrthogonalTo (line 187) | public bool IsOrthogonalTo(ILinearObject obj)
method IsParallelTo (line 195) | public bool IsParallelTo(IPlanarObject obj)
method IsNotParallelTo (line 203) | public bool IsNotParallelTo(IPlanarObject obj)
method IsOrthogonalTo (line 211) | public bool IsOrthogonalTo(IPlanarObject obj)
method IsCoplanarTo (line 219) | public bool IsCoplanarTo(IPlanarObject obj)
method IsCoplanarTo (line 227) | public bool IsCoplanarTo(ILinearObject obj)
method BoundingBox (line 253) | public Box3d BoundingBox(Coord3d coord = null)
method AABB (line 268) | public AABB AABB()
method IsInside (line 291) | public bool IsInside(Box3d box)
method ParametricForm (line 324) | public Point3d ParametricForm(double t)
method DistanceTo (line 336) | public double DistanceTo(Plane3d s)
method DistanceTo (line 359) | public double DistanceTo(Plane3d p, out Point3d point_on_circle, out P...
method DistanceTo (line 397) | public double DistanceTo(Point3d p)
method ClosestPoint (line 416) | public Point3d ClosestPoint(Point3d p)
method ClosestPointOnBoundary (line 434) | public Point3d ClosestPointOnBoundary(Point3d p)
method DistanceTo (line 447) | public double DistanceTo(Circle3d c)
method DistanceTo (line 457) | public double DistanceTo(Circle3d c, double tolerance)
method DistanceTo (line 525) | public double DistanceTo(Circle3d c, out Point3d p1, out Point3d p2)
method DistanceTo (line 538) | public double DistanceTo(Circle3d c, out Point3d p1, out Point3d p2, d...
method DistanceGreater (line 632) | public bool DistanceGreater(Circle3d c, double threshold, double toler...
method _distance_circle_to_circle_new (line 702) | private double _distance_circle_to_circle_new(Circle3d c1, Circle3d c2...
method _distance_circle_to_circle (line 729) | private double _distance_circle_to_circle(Circle3d c1, Circle3d c2, ou...
method DistanceTo (line 842) | public double DistanceTo(Sphere s)
method DistanceTo (line 852) | public double DistanceTo(Sphere s, double tolerance)
method DistanceTo (line 877) | public double DistanceTo(Sphere s, out Point3d p1, out Point3d p2)
method DistanceTo (line 890) | public double DistanceTo(Sphere s, out Point3d p1, out Point3d p2, dou...
method _distance_circle_to_sphere (line 929) | private double _distance_circle_to_sphere(Circle3d c1, Sphere c2, out ...
method DistanceTo (line 1006) | public double DistanceTo(Line3d l)
method DistanceToBoundary (line 1016) | public double DistanceToBoundary(Line3d l)
method DistanceTo (line 1029) | public double DistanceTo(Line3d l, out Point3d point_on_circle, out Po...
method DistanceToBoundary (line 1041) | public double DistanceToBoundary(Line3d l, out Point3d point_on_circle...
method DistanceTo (line 1050) | public double DistanceTo(Ray3d r)
method DistanceTo (line 1062) | public double DistanceTo(Ray3d r, out Point3d point_on_circle, out Poi...
method DistanceTo (line 1076) | public double DistanceTo(Segment3d s)
method DistanceTo (line 1088) | public double DistanceTo(Segment3d s, out Point3d point_on_circle, out...
method _distance_circle_to_line (line 1150) | private double _distance_circle_to_line(Line3d l, out Point3d p1, out ...
method _distance_circle_boundary_to_line (line 1180) | private double _distance_circle_boundary_to_line(Line3d l, out Point3d...
method DistanceTo (line 1313) | public double DistanceTo(Triangle t)
method DistanceTo (line 1325) | public double DistanceTo(Triangle t, out Point3d point_on_circle, out ...
method DistanceTo (line 1359) | public double DistanceTo(Box3d box)
method DistanceTo (line 1367) | public double DistanceTo(ConvexPolyhedron cp)
method Intersects (line 1376) | public bool Intersects(Sphere s)
method Intersects (line 1402) | public bool Intersects(Circle3d c)
method _circle_circle_intersection_check_2 (line 1473) | private bool _circle_circle_intersection_check_2(Circle3d c)
method _circle_circle_intersection_check (line 1502) | private bool _circle_circle_intersection_check(Circle3d c)
method Intersects (line 1578) | public bool Intersects(Triangle t)
method Intersects (line 1610) | public bool Intersects(Box3d box)
method Intersects (line 1618) | public bool Intersects(Segment3d s)
method ProjectionTo (line 1626) | public Ellipse ProjectionTo(Plane3d s)
method ProjectionTo (line 1634) | public Segment3d ProjectionTo(Line3d l)
method IntersectionWith (line 1646) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 1721) | public object IntersectionWith(Segment3d s)
method IntersectionWith (line 1765) | public object IntersectionWith(Ray3d r)
method IntersectionWith (line 1809) | public object IntersectionWith(Plane3d s)
method IntersectionWith (line 1875) | public object IntersectionWith(Circle3d c)
method _PointLocation (line 2016) | internal override int _PointLocation(Point3d p)
method AngleTo (line 2058) | public double AngleTo(ILinearObject obj)
method AngleToDeg (line 2065) | public double AngleToDeg(ILinearObject obj)
method AngleTo (line 2073) | public double AngleTo(IPlanarObject obj)
method AngleToDeg (line 2080) | public double AngleToDeg(IPlanarObject obj)
method Translate (line 2090) | public Circle3d Translate(Vector3d v)
method Rotate (line 2098) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 2107) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 2116) | public Circle3d Rotate(Rotation r, Point3d p)
method ReflectIn (line 2124) | public Circle3d ReflectIn(Point3d p)
method ReflectIn (line 2132) | public Circle3d ReflectIn(Line3d l)
method ReflectIn (line 2140) | public Circle3d ReflectIn(Plane3d s)
method Scale (line 2148) | public virtual Circle3d Scale(double scale, Point3d scaling_center)
method Equals (line 2158) | public override bool Equals(object obj)
method GetHashCode (line 2181) | public override int GetHashCode()
method ToString (line 2189) | public override String ToString()
method ToString (line 2197) | public String ToString(bool full_precision = false)
method ToString (line 2205) | public String ToString(Coord3d coord, bool full_precision = false)
method ToString (line 2230) | public String ToString(Coord3d coord, bool full_precision = false, boo...
FILE: GeometRi/ConvexPolyhedron.cs
class ConvexPolyhedron (line 11) | #if NET20_OR_GREATER
type Edge (line 27) | #if NET20_OR_GREATER
method Edge (line 34) | public Edge(int P1, int P2)
type IVertex (line 57) | public interface IVertex
type Face (line 62) | #if NET20_OR_GREATER
method Face (line 71) | public Face(int numVertices, int[] vertex)
method Extrude (line 112) | public ConvexPolyhedron Extrude(double distance, bool symmetrical = ...
method Extrude (line 120) | public ConvexPolyhedron Extrude(Vector3d direction, double distance,...
method UpdateNormal (line 187) | internal void UpdateNormal()
method ConvexPolyhedron (line 207) | public ConvexPolyhedron(int numVertices, int numEdges, int numFaces, P...
method FromTetrahedron (line 237) | public static ConvexPolyhedron FromTetrahedron(Tetrahedron t)
method Cube (line 265) | public static ConvexPolyhedron Cube(Point3d p_min, Point3d p_max)
method FromBox (line 273) | public static ConvexPolyhedron FromBox(Box3d box)
method Octahedron (line 318) | public static ConvexPolyhedron Octahedron()
method Icosahedron (line 365) | public static ConvexPolyhedron Icosahedron()
method Dodecahedron (line 462) | public static ConvexPolyhedron Dodecahedron()
method RhombicDodecahedron (line 547) | public static ConvexPolyhedron RhombicDodecahedron()
method Cuboctahedron (line 616) | public static ConvexPolyhedron Cuboctahedron()
method Rhombicuboctahedron (line 688) | public static ConvexPolyhedron Rhombicuboctahedron(double delta)
method Copy (line 912) | public ConvexPolyhedron Copy()
method CheckFaceOrientation (line 943) | private void CheckFaceOrientation()
method ReverseFace (line 956) | private Face ReverseFace(Face face)
method BoundingBox (line 984) | public Box3d BoundingBox(Coord3d coord = null)
method AABB (line 992) | public AABB AABB()
method DistanceTo (line 1020) | public double DistanceTo(Point3d p)
method DistanceTo (line 1080) | public double DistanceTo(Circle3d c)
method DistanceTo (line 1118) | public double DistanceTo(Sphere s)
method DistanceTo (line 1128) | public double DistanceTo(ConvexPolyhedron c)
method DistanceTo (line 1329) | public double DistanceTo(ConvexPolyhedron c, out Point3d point_on_this...
method DistanceTo (line 1536) | public double DistanceTo(Triangle t)
method DistanceTo (line 1548) | public double DistanceTo(Triangle t, out Point3d point_on_polyhedron, ...
method DistanceTo (line 1751) | public double DistanceTo(Segment3d c, out Point3d point_on_polyhedron,...
method DistanceTo (line 1887) | public double DistanceTo(Segment3d s)
method _get_common_point (line 1892) | internal Point3d _get_common_point(ConvexPolyhedron cp)
method Intersects (line 1951) | public bool Intersects(ConvexPolyhedron c)
method Intersects (line 2023) | public bool Intersects(Segment3d c)
method Intersects (line 2075) | public bool Intersects(Triangle t)
method WhichSide (line 2139) | private int WhichSide(Point3d[] vertex, Vector3d P, Vector3d D, double...
method WhichSide (line 2168) | private int WhichSide(Point3d[] vertex, Point3d P, Point3d D, double t...
method WhichSide (line 2197) | private int WhichSide(Point3d[] vertex, Point3d P, Vector3d D, double ...
method WhichSide (line 2226) | private int WhichSide(IVector[] vertex, IVector P, IVector D, double t...
method IsInside (line 2259) | public bool IsInside(Box3d box)
method Intersects (line 2272) | public bool Intersects(Box3d box)
method _PointLocation (line 2284) | internal override int _PointLocation(Point3d p)
method _SameSide (line 2310) | private int _SameSide(Point3d a, Vector3d normal, Point3d p)
method Translate (line 2333) | public ConvexPolyhedron Translate(Vector3d v)
method Rotate (line 2348) | public ConvexPolyhedron Rotate(Rotation r, Point3d p)
method Scale (line 2369) | public ConvexPolyhedron Scale(double scale)
method Scale (line 2377) | public ConvexPolyhedron Scale(double scale, Point3d scaling_center)
method Scale (line 2392) | public virtual ConvexPolyhedron Scale(double scale_x, double scale_y, ...
method Scale (line 2415) | public virtual ConvexPolyhedron Scale(double scale_x, double scale_y, ...
method ToString (line 2425) | public override string ToString()
method ToString (line 2433) | public string ToString(bool full_precision = false)
method ToString (line 2441) | public string ToString(Coord3d coord, bool full_precision = false)
FILE: GeometRi/Coord3D.cs
class Coord3d (line 9) | #if NET20_OR_GREATER
method Coord3d (line 27) | public Coord3d(string name = "")
method Coord3d (line 48) | public Coord3d(Point3d p, Matrix3d m, string name = "")
method Coord3d (line 75) | public Coord3d(Point3d p, Vector3d v1, Vector3d v2, string name = "")
method Coord3d (line 107) | public Coord3d(Point3d p1, Point3d p2, Point3d p3, string name = "")
method Coord3d (line 141) | public Coord3d(Point3d p, double[] d1, double[] d2, string name = "")
method Copy (line 171) | public Coord3d Copy()
method Rotate (line 269) | public void Rotate(Rotation r)
method Rotate (line 279) | public void Rotate(Vector3d axis, double angle)
method RotateDeg (line 289) | public void RotateDeg(Vector3d axis, double angle)
method Equals (line 298) | public override bool Equals(object obj)
method GetHashCode (line 306) | public override int GetHashCode()
method ToString (line 314) | public override String ToString()
FILE: GeometRi/Ellipse.cs
class Ellipse (line 9) | #if NET20_OR_GREATER
method Ellipse (line 25) | public Ellipse(Point3d Center, Vector3d v1, Vector3d v2)
method Copy (line 48) | public Ellipse Copy()
method IsParallelTo (line 162) | public bool IsParallelTo(ILinearObject obj)
method IsNotParallelTo (line 170) | public bool IsNotParallelTo(ILinearObject obj)
method IsOrthogonalTo (line 178) | public bool IsOrthogonalTo(ILinearObject obj)
method IsParallelTo (line 186) | public bool IsParallelTo(IPlanarObject obj)
method IsNotParallelTo (line 194) | public bool IsNotParallelTo(IPlanarObject obj)
method IsOrthogonalTo (line 202) | public bool IsOrthogonalTo(IPlanarObject obj)
method IsCoplanarTo (line 210) | public bool IsCoplanarTo(IPlanarObject obj)
method IsCoplanarTo (line 218) | public bool IsCoplanarTo(ILinearObject obj)
method BoundingBox (line 244) | public Box3d BoundingBox(Coord3d coord = null)
method AABB (line 259) | public AABB AABB()
method ParametricForm (line 283) | public Point3d ParametricForm(double t)
method ProjectionTo (line 293) | public Segment3d ProjectionTo(Line3d l)
method ProjectionTo (line 315) | public Ellipse ProjectionTo(Plane3d s)
method IntersectionWith (line 336) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 428) | public object IntersectionWith(Plane3d s)
method IntersectionWith (line 469) | public object IntersectionWith(Segment3d s)
method IntersectionWith (line 513) | public object IntersectionWith(Ray3d r)
method _PointLocation (line 553) | internal override int _PointLocation(Point3d p)
method ClosestPoint (line 594) | public Point3d ClosestPoint(Point3d p)
method AngleTo (line 638) | public double AngleTo(ILinearObject obj)
method AngleToDeg (line 645) | public double AngleToDeg(ILinearObject obj)
method AngleTo (line 653) | public double AngleTo(IPlanarObject obj)
method AngleToDeg (line 660) | public double AngleToDeg(IPlanarObject obj)
method Translate (line 670) | public Ellipse Translate(Vector3d v)
method Rotate (line 678) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 687) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 696) | public Ellipse Rotate(Rotation r, Point3d p)
method ReflectIn (line 704) | public Ellipse ReflectIn(Point3d p)
method ReflectIn (line 712) | public Ellipse ReflectIn(Line3d l)
method ReflectIn (line 720) | public Ellipse ReflectIn(Plane3d s)
method Scale (line 728) | public virtual Ellipse Scale(double scale, Point3d scaling_center)
method Equals (line 738) | public override bool Equals(object obj)
method GetHashCode (line 808) | public override int GetHashCode()
method ToString (line 816) | public override String ToString()
method ToString (line 824) | public String ToString(Coord3d coord)
FILE: GeometRi/Ellipsoid.cs
class Ellipsoid (line 9) | #if NET20_OR_GREATER
method Ellipsoid (line 27) | public Ellipsoid(Point3d Center, Vector3d v1, Vector3d v2, Vector3d v3)
method Copy (line 81) | public Ellipsoid Copy()
method BoundingBox (line 197) | public Box3d BoundingBox(Coord3d coord = null)
method AABB (line 212) | public AABB AABB()
method ProjectionTo (line 236) | public Segment3d ProjectionTo(Line3d l)
method IntersectionWith (line 258) | public object IntersectionWith(Line3d s)
method IntersectionWith (line 338) | public object IntersectionWith(Segment3d s)
method IntersectionWith (line 382) | public object IntersectionWith(Ray3d r)
method IntersectionWith (line 426) | public object IntersectionWith(Plane3d plane)
method Intersects (line 537) | public bool Intersects(Sphere e, double accuracy)
method Intersects (line 545) | public bool Intersects(Sphere e)
method IntersectionCheck (line 556) | public int IntersectionCheck(Sphere e)
method IntersectionCheck (line 567) | public int IntersectionCheck(Sphere e, double accuracy)
method _Intersects (line 578) | internal int _Intersects(Sphere e, double accuracy)
method Intersects (line 653) | private bool Intersects(Ellipsoid e, double accuracy)
method Intersects (line 661) | private bool Intersects(Ellipsoid e)
method IntersectionCheck (line 672) | private int IntersectionCheck(Ellipsoid e)
method IntersectionCheck (line 683) | private int IntersectionCheck(Ellipsoid e, double accuracy)
method _Intersects (line 694) | internal int _Intersects(Ellipsoid e, double accuracy)
method _PointLocation (line 791) | internal override int _PointLocation(Point3d p)
method ClosestPoint (line 827) | public Point3d ClosestPoint(Point3d p)
method ClosestPoint (line 835) | public Point3d ClosestPoint(Point3d p, double tolerance)
method DistanceTo (line 899) | public double DistanceTo(Ellipsoid e)
method DistanceTo (line 907) | public double DistanceTo(Ellipsoid e, double tolerance)
method Translate (line 934) | public Ellipsoid Translate(Vector3d v)
method Rotate (line 942) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 951) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 960) | public Ellipsoid Rotate(Rotation r, Point3d p)
method ReflectIn (line 968) | public Ellipsoid ReflectIn(Point3d p)
method ReflectIn (line 976) | public Ellipsoid ReflectIn(Line3d l)
method ReflectIn (line 984) | public Ellipsoid ReflectIn(Plane3d s)
method Scale (line 992) | public virtual Ellipsoid Scale(double scale, Point3d scaling_center)
method Equals (line 1002) | public override bool Equals(object obj)
method GetHashCode (line 1123) | public override int GetHashCode()
method ToString (line 1131) | public override String ToString()
method ToString (line 1139) | public String ToString(Coord3d coord)
FILE: GeometRi/GeometRi3D.cs
class GeometRi3D (line 9) | public static class GeometRi3D
method AlmostEqual (line 47) | public static bool AlmostEqual(double a, double b)
method AlmostEqual (line 62) | public static bool AlmostEqual(double a, double b, double tolerance)
method NotEqual (line 77) | public static bool NotEqual(double a, double b)
method NotEqual (line 92) | public static bool NotEqual(double a, double b, double tolerance)
method Greater (line 107) | public static bool Greater(double a, double b)
method Greater (line 122) | public static bool Greater(double a, double b, double tolerance)
method Smaller (line 137) | public static bool Smaller(double a, double b)
method Smaller (line 152) | public static bool Smaller(double a, double b, double tolerance)
method HashFunction (line 164) | static internal int HashFunction(int n1, int n2)
method HashFunction (line 169) | static internal int HashFunction(int n1, int n2, int n3)
method HashFunction (line 175) | static internal int HashFunction(int n1, int n2, int n3, int n4)
method Clamp (line 185) | public static T Clamp<T>(T value, T min, T max) where T : IComparable<T>
method GetAngle (line 195) | static internal double GetAngle(ILinearObject obj1, ILinearObject obj2)
method GetAngle (line 224) | static internal double GetAngle(ILinearObject obj1, IPlanarObject obj2)
method GetAngle (line 246) | static internal double GetAngle(IPlanarObject obj1, ILinearObject obj2)
method GetAngle (line 251) | static internal double GetAngle(IPlanarObject obj1, IPlanarObject obj2)
method _coplanar (line 273) | static internal bool _coplanar(IPlanarObject obj1, IPlanarObject obj2)
method _coplanar (line 281) | static internal bool _coplanar(ILinearObject obj1, ILinearObject obj2)
method _coplanar (line 292) | static internal bool _coplanar(IPlanarObject obj1, ILinearObject obj2)
method _coplanar (line 299) | static internal bool _coplanar(ILinearObject obj1, IPlanarObject obj2)
FILE: GeometRi/Interface.cs
type ILinearObject (line 9) | public interface ILinearObject
type IPlanarObject (line 19) | public interface IPlanarObject
type IFiniteObject (line 30) | public interface IFiniteObject
method BoundingBox (line 32) | Box3d BoundingBox(Coord3d coord);
type IVector (line 40) | public interface IVector
method Dot (line 43) | double Dot(IVector v);
method Subtract (line 44) | IVector Subtract(IVector v);
FILE: GeometRi/Line3D.cs
class Line3d (line 9) | #if NET20_OR_GREATER
method Line3d (line 24) | public Line3d()
method Line3d (line 35) | public Line3d(Point3d p, Vector3d v)
method Line3d (line 46) | public Line3d(Point3d p1, Point3d p2)
method Copy (line 56) | public Line3d Copy()
method IsParallelTo (line 96) | public bool IsParallelTo(ILinearObject obj)
method IsNotParallelTo (line 104) | public bool IsNotParallelTo(ILinearObject obj)
method IsOrthogonalTo (line 112) | public bool IsOrthogonalTo(ILinearObject obj)
method IsParallelTo (line 120) | public bool IsParallelTo(IPlanarObject obj)
method IsNotParallelTo (line 128) | public bool IsNotParallelTo(IPlanarObject obj)
method IsOrthogonalTo (line 136) | public bool IsOrthogonalTo(IPlanarObject obj)
method IsCoplanarTo (line 144) | public bool IsCoplanarTo(IPlanarObject obj)
method IsCoplanarTo (line 152) | public bool IsCoplanarTo(ILinearObject obj)
method DistanceTo (line 162) | public double DistanceTo(Point3d p)
method DistanceTo (line 170) | public double DistanceTo(Ray3d r)
method DistanceTo (line 178) | public double DistanceTo(Segment3d s)
method DistanceTo (line 186) | public virtual double DistanceTo(Line3d l)
method DistanceTo (line 208) | public double DistanceTo(Circle3d c)
method DistanceTo (line 219) | public double DistanceTo(Circle3d c, out Point3d point_on_line, out Po...
method PerpendicularTo (line 229) | public virtual Point3d PerpendicularTo(Line3d l)
method IntersectionWith (line 254) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 281) | public virtual object IntersectionWith(Plane3d s)
method IntersectionWith (line 290) | public object IntersectionWith(Sphere s)
method IntersectionWith (line 299) | public object IntersectionWith(Ellipsoid e)
method IntersectionWith (line 308) | public object IntersectionWith(Ellipse e)
method IntersectionWith (line 317) | public object IntersectionWith(Circle3d c)
method IntersectionWith (line 326) | public object IntersectionWith(Segment3d s)
method IntersectionWith (line 335) | public object IntersectionWith(Triangle t)
method IntersectionWith (line 344) | public object IntersectionWith(Box3d b)
method ProjectionTo (line 353) | public virtual object ProjectionTo(Plane3d s)
method AngleTo (line 372) | public double AngleTo(ILinearObject obj)
method AngleToDeg (line 379) | public double AngleToDeg(ILinearObject obj)
method AngleTo (line 387) | public double AngleTo(IPlanarObject obj)
method AngleToDeg (line 394) | public double AngleToDeg(IPlanarObject obj)
method Translate (line 405) | public virtual Line3d Translate(Vector3d v)
method Rotate (line 415) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 427) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 439) | public virtual Line3d Rotate(Rotation r, Point3d p)
method ReflectIn (line 447) | public virtual Line3d ReflectIn(Point3d p)
method ReflectIn (line 455) | public virtual Line3d ReflectIn(Line3d l)
method ReflectIn (line 463) | public virtual Line3d ReflectIn(Plane3d s)
method Equals (line 472) | public override bool Equals(object obj)
method GetHashCode (line 509) | public override int GetHashCode()
method ToString (line 517) | public override String ToString()
method ToString (line 525) | public String ToString(Coord3d coord)
FILE: GeometRi/Matrix3D.cs
class Matrix3d (line 9) | #if NET20_OR_GREATER
method Matrix3d (line 21) | public Matrix3d()
method Matrix3d (line 32) | public Matrix3d(Vector3d row1, Vector3d row2, Vector3d row3)
method Matrix3d (line 39) | public Matrix3d(double[] row1, double[] row2, double[] row3)
method Identity (line 50) | public static Matrix3d Identity()
method DiagonalMatrix (line 59) | public static Matrix3d DiagonalMatrix(double a11, double a22, double a33)
method Copy (line 71) | public Matrix3d Copy()
method Add (line 209) | public Matrix3d Add(double a)
method Add (line 221) | public Matrix3d Add(Matrix3d a)
method Subtract (line 233) | public Matrix3d Subtract(Matrix3d a)
method Mult (line 246) | public Matrix3d Mult(double a)
method Mult (line 258) | public Vector3d Mult(Vector3d a)
method TransposeMult (line 266) | internal Vector3d TransposeMult(Vector3d a)
method Mult (line 274) | public Point3d Mult(Point3d p)
method TransposeMult (line 281) | internal Point3d TransposeMult(Point3d p)
method Mult (line 288) | public Matrix3d Mult(Matrix3d a)
method Inverse (line 304) | public Matrix3d Inverse()
method Transpose (line 342) | public Matrix3d Transpose()
method RotationMatrix (line 359) | public static Matrix3d RotationMatrix(Vector3d axis, double alpha)
method Equals (line 384) | public override bool Equals(object obj)
method GetHashCode (line 405) | public override int GetHashCode()
method ToString (line 413) | public override string ToString()
FILE: GeometRi/Plane3D.cs
class Plane3d (line 9) | #if NET20_OR_GREATER
method CheckFields (line 22) | private void CheckFields()
method ClearCache (line 32) | private void ClearCache()
method Plane3d (line 41) | public Plane3d()
method Plane3d (line 55) | public Plane3d(double a, double b, double c, double d, Coord3d coord =...
method Plane3d (line 82) | public Plane3d(Point3d p1, Point3d p2, Point3d p3)
method Plane3d (line 93) | public Plane3d(Point3d p1, Vector3d v1, Vector3d v2)
method Plane3d (line 104) | public Plane3d(Point3d p1, Vector3d v1)
method Copy (line 114) | public Plane3d Copy()
method SetCoord (line 147) | public void SetCoord(Coord3d coord = null)
method IsParallelTo (line 221) | public bool IsParallelTo(ILinearObject obj)
method IsNotParallelTo (line 229) | public bool IsNotParallelTo(ILinearObject obj)
method IsOrthogonalTo (line 237) | public bool IsOrthogonalTo(ILinearObject obj)
method IsParallelTo (line 245) | public bool IsParallelTo(IPlanarObject obj)
method IsNotParallelTo (line 253) | public bool IsNotParallelTo(IPlanarObject obj)
method IsOrthogonalTo (line 261) | public bool IsOrthogonalTo(IPlanarObject obj)
method IsCoplanarTo (line 269) | public bool IsCoplanarTo(IPlanarObject obj)
method IsCoplanarTo (line 277) | public bool IsCoplanarTo(ILinearObject obj)
method DistanceTo (line 286) | public double DistanceTo(Circle3d c)
method DistanceTo (line 297) | public double DistanceTo(Circle3d c, out Point3d point_on_plane, out P...
method IntersectionWith (line 306) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 336) | public object IntersectionWith(Plane3d s2, Plane3d s3)
method IntersectionWith (line 391) | public object IntersectionWith(Plane3d s2)
method IntersectionWith (line 434) | public object IntersectionWith(Sphere s)
method IntersectionWith (line 443) | public object IntersectionWith(Ellipsoid e)
method IntersectionWith (line 452) | public object IntersectionWith(Circle3d c)
method IntersectionWith (line 461) | public object IntersectionWith(Triangle t)
method AngleTo (line 470) | public double AngleTo(ILinearObject obj)
method AngleToDeg (line 477) | public double AngleToDeg(ILinearObject obj)
method AngleTo (line 485) | public double AngleTo(IPlanarObject obj)
method AngleToDeg (line 492) | public double AngleToDeg(IPlanarObject obj)
method Translate (line 503) | public Plane3d Translate(Vector3d v)
method Rotate (line 511) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 520) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 529) | public Plane3d Rotate(Rotation r, Point3d p)
method ReflectIn (line 537) | public Plane3d ReflectIn(Point3d p)
method ReflectIn (line 545) | public Plane3d ReflectIn(Line3d l)
method ReflectIn (line 553) | public Plane3d ReflectIn(Plane3d s)
method Equals (line 562) | public override bool Equals(object obj)
method GetHashCode (line 590) | public override int GetHashCode()
method ToString (line 598) | public override String ToString()
method ToString (line 606) | public String ToString(Coord3d coord)
FILE: GeometRi/Point3D.cs
class Point3d (line 9) | #if NET20_OR_GREATER
method Point3d (line 25) | public Point3d(Coord3d coord = null)
method Point3d (line 37) | public Point3d(double x, double y, double z, Coord3d coord = null)
method Point3d (line 49) | public Point3d(double[] a, Coord3d coord = null)
method Copy (line 63) | public Point3d Copy()
method ConvertTo (line 114) | public Point3d ConvertTo(Coord3d coord)
method ConvertToGlobal (line 129) | public Point3d ConvertToGlobal()
method Add (line 145) | public Point3d Add(Point3d p)
method Add (line 151) | internal Point3d Add(Point3d p, double a, double b)
method Add (line 158) | public Point3d Add(Vector3d p)
method Subtract (line 164) | public Point3d Subtract(Point3d p)
method Subtract (line 170) | internal Point3d Subtract(Point3d p, double a, double b)
method Subtract (line 176) | public Point3d Subtract(Vector3d p)
method Subtract (line 182) | internal Point3d Subtract(Vector3d v, double a)
method Scale (line 188) | public Point3d Scale(double a)
method Dot (line 192) | internal double Dot(Point3d p)
method Dot (line 198) | internal double Dot(Vector3d p)
method Cross (line 204) | internal Point3d Cross(Point3d v)
method DistanceTo (line 235) | public double DistanceTo(Point3d p)
method DistanceSquared (line 245) | public double DistanceSquared(Point3d p)
method DistanceTo (line 257) | public double DistanceTo(Line3d l)
method DistanceSquared (line 263) | public double DistanceSquared(Line3d l)
method DistanceTo (line 272) | public double DistanceTo(Plane3d s)
method DistanceSquared (line 277) | public double DistanceSquared(Plane3d s)
method DistanceTo (line 286) | public double DistanceTo(Ray3d r)
method DistanceSquared (line 299) | public double DistanceSquared(Ray3d r)
method DistanceTo (line 315) | public double DistanceTo(Segment3d s)
method DistanceTo (line 348) | public double DistanceTo(Segment3d s, out Point3d closest_point)
method DistanceSquared (line 381) | public double DistanceSquared(Segment3d s)
method DistanceTo (line 414) | public double DistanceTo(Sphere s)
method DistanceTo (line 422) | public double DistanceTo(Circle3d c)
method DistanceTo (line 430) | public double DistanceTo(Box3d box)
method DistanceTo (line 438) | public double DistanceTo(AABB box)
method DistanceTo (line 446) | public double DistanceTo(Triangle t)
method DistanceSquared (line 451) | public double DistanceSquared(Triangle t)
method DistanceTo (line 459) | public double DistanceTo(Triangle t, out Point3d closest_point)
method ClosestPoint (line 470) | public Point3d ClosestPoint(Circle3d c)
method ClosestPoint (line 478) | public Point3d ClosestPoint(Box3d box)
method ClosestPoint (line 486) | public Point3d ClosestPoint(Triangle t)
method ClosestPoint (line 494) | public Point3d ClosestPoint(Sphere s)
method ProjectionTo (line 503) | public Point3d ProjectionTo(Plane3d s)
method ProjectionTo (line 511) | public Point3d ProjectionTo(Line3d l)
method ProjectionTo (line 523) | public Point3d ProjectionTo(Sphere s)
method BelongsTo (line 533) | public bool BelongsTo(Line3d l)
method BelongsTo (line 542) | public bool BelongsTo(Ray3d l)
method BelongsTo (line 564) | public bool BelongsTo(Plane3d s)
method BelongsTo (line 596) | public bool BelongsTo(FiniteObject obj)
method IsInside (line 607) | public bool IsInside(FiniteObject obj)
method IsOutside (line 618) | public bool IsOutside(FiniteObject obj)
method IsOnBoundary (line 629) | public bool IsOnBoundary(FiniteObject obj)
method Translate (line 644) | public Point3d Translate(Vector3d v)
method Rotate (line 654) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 663) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 674) | public Point3d Rotate(Rotation r)
method Rotate (line 683) | public Point3d Rotate(Rotation r, Point3d p)
method ReflectIn (line 693) | public Point3d ReflectIn(Point3d p)
method ReflectIn (line 704) | public Point3d ReflectIn(Line3d l)
method ReflectIn (line 713) | public Point3d ReflectIn(Plane3d s)
method CollinearPoints (line 723) | public static bool CollinearPoints(Point3d A, Point3d B, Point3d C)
method Equals (line 740) | public override bool Equals(object obj)
method GetHashCode (line 769) | public override int GetHashCode()
method ToString (line 777) | public override String ToString()
method ToString (line 785) | public String ToString(Coord3d coord)
FILE: GeometRi/Quaternion.cs
class Quaternion (line 9) | #if NET20_OR_GREATER
method Quaternion (line 23) | public Quaternion(Coord3d coord = null)
method Quaternion (line 33) | public Quaternion(double w, double x, double y, double z, Coord3d coor...
method Quaternion (line 43) | public Quaternion(double[] q, Coord3d coord = null)
method Quaternion (line 57) | public Quaternion(Vector3d axis, double angle)
method Quaternion (line 73) | public Quaternion(Matrix3d m, Coord3d coord = null)
method Copy (line 114) | public Quaternion Copy()
method Normalize (line 255) | public void Normalize()
method Add (line 264) | public Quaternion Add(Quaternion q)
method Subtract (line 277) | public Quaternion Subtract(Quaternion q)
method Mult (line 290) | public Quaternion Mult (Quaternion q)
method Scale (line 305) | public Quaternion Scale(double a)
method Inverse (line 310) | public Quaternion Inverse()
method ConvertToGlobal (line 318) | public Quaternion ConvertToGlobal()
method ConvertTo (line 336) | public Quaternion ConvertTo(Coord3d coord)
method ToRotationMatrix (line 351) | public Matrix3d ToRotationMatrix()
method SLERP (line 376) | public static Quaternion SLERP(Quaternion q1, Quaternion q2, double t)
method Equals (line 413) | public override bool Equals(object obj)
method GetHashCode (line 427) | public override int GetHashCode()
method ToString (line 435) | public override String ToString()
method ToString (line 443) | public string ToString(Coord3d coord)
FILE: GeometRi/Ray3D.cs
class Ray3d (line 9) | #if NET20_OR_GREATER
method Ray3d (line 22) | public Ray3d()
method Ray3d (line 31) | public Ray3d(Point3d p, Vector3d v)
method Copy (line 40) | public Ray3d Copy()
method IsParallelTo (line 74) | public bool IsParallelTo(ILinearObject obj)
method IsNotParallelTo (line 82) | public bool IsNotParallelTo(ILinearObject obj)
method IsOrthogonalTo (line 90) | public bool IsOrthogonalTo(ILinearObject obj)
method IsParallelTo (line 98) | public bool IsParallelTo(IPlanarObject obj)
method IsNotParallelTo (line 106) | public bool IsNotParallelTo(IPlanarObject obj)
method IsOrthogonalTo (line 114) | public bool IsOrthogonalTo(IPlanarObject obj)
method IsCoplanarTo (line 122) | public bool IsCoplanarTo(IPlanarObject obj)
method IsCoplanarTo (line 130) | public bool IsCoplanarTo(ILinearObject obj)
method DistanceTo (line 148) | public double DistanceTo(Point3d p)
method DistanceTo (line 156) | public double DistanceTo(Line3d l)
method DistanceTo (line 185) | public double DistanceTo(Segment3d s)
method DistanceTo (line 193) | public double DistanceTo(Ray3d r)
method DistanceTo (line 233) | public double DistanceTo(Circle3d c)
method DistanceTo (line 244) | public double DistanceTo(Circle3d c, out Point3d point_on_ray, out Poi...
method PerpendicularTo (line 254) | public Point3d PerpendicularTo(Line3d l)
method IntersectionWith (line 283) | public object IntersectionWith(Plane3d s)
method IntersectionWith (line 322) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 353) | public object IntersectionWith(Ray3d r)
method IntersectionWith (line 409) | public object IntersectionWith(Segment3d s)
method IntersectionWith (line 481) | public object IntersectionWith(Sphere s)
method IntersectionWith (line 490) | public object IntersectionWith(Ellipse e)
method IntersectionWith (line 499) | public object IntersectionWith(Ellipsoid e)
method IntersectionWith (line 508) | public object IntersectionWith(Circle3d c)
method IntersectionWith (line 517) | public object IntersectionWith(Triangle t)
method IntersectionWith (line 526) | public object IntersectionWith(Box3d b)
method ProjectionTo (line 535) | public object ProjectionTo(Plane3d s)
method AngleTo (line 554) | public double AngleTo(ILinearObject obj)
method AngleToDeg (line 561) | public double AngleToDeg(ILinearObject obj)
method AngleTo (line 569) | public double AngleTo(IPlanarObject obj)
method AngleToDeg (line 576) | public double AngleToDeg(IPlanarObject obj)
method Translate (line 586) | public Ray3d Translate(Vector3d v)
method Rotate (line 596) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 605) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 614) | public Ray3d Rotate(Rotation r, Point3d p)
method ReflectIn (line 622) | public Ray3d ReflectIn(Point3d p)
method ReflectIn (line 630) | public Ray3d ReflectIn(Line3d l)
method ReflectIn (line 638) | public Ray3d ReflectIn(Plane3d s)
method Equals (line 647) | public override bool Equals(object obj)
method GetHashCode (line 675) | public override int GetHashCode()
method ToString (line 683) | public override String ToString()
method ToString (line 691) | public String ToString(Coord3d coord)
FILE: GeometRi/Rotation.cs
class Rotation (line 10) | #if NET20_OR_GREATER
method Rotation (line 25) | public Rotation()
method Rotation (line 34) | public Rotation(Coord3d coord)
method Rotation (line 52) | public Rotation(Matrix3d m, Coord3d coord = null)
method Rotation (line 62) | public Rotation(Quaternion q)
method Rotation (line 73) | public Rotation(Vector3d axis, double alpha)
method Random (line 120) | public static Rotation Random()
method Copy (line 128) | public Rotation Copy()
method FromEulerAngles (line 222) | public static Rotation FromEulerAngles(double alpha, double beta, doub...
method CharToVector (line 249) | private static Vector3d CharToVector(char c, Coord3d coord)
method ToEulerAngles (line 268) | public double[] ToEulerAngles(string RotationOrder, Coord3d coord = null)
method SLERP (line 715) | public static Rotation SLERP(Rotation r1, Rotation r2, double t)
method Mult (line 723) | public Rotation Mult(Rotation r)
method Mult (line 733) | public Vector3d Mult(Vector3d v)
method Mult (line 742) | public Point3d Mult(Point3d p)
method ConvertToGlobal (line 750) | public Rotation ConvertToGlobal()
method ConvertTo (line 768) | public Rotation ConvertTo(Coord3d coord)
method Equals (line 786) | public override bool Equals(object obj)
method GetHashCode (line 807) | public override int GetHashCode()
method ToString (line 817) | public override string ToString()
method ToString (line 825) | public string ToString(Coord3d coord)
FILE: GeometRi/Segment3D.cs
class Segment3d (line 9) | #if NET20_OR_GREATER
method ClearCache (line 24) | private void ClearCache()
method Segment3d (line 38) | public Segment3d(Point3d p1, Point3d p2)
method Copy (line 47) | public Segment3d Copy()
method AABB (line 175) | public AABB AABB()
method IsParallelTo (line 184) | public bool IsParallelTo(ILinearObject obj)
method IsNotParallelTo (line 192) | public bool IsNotParallelTo(ILinearObject obj)
method IsOrthogonalTo (line 200) | public bool IsOrthogonalTo(ILinearObject obj)
method IsParallelTo (line 208) | public bool IsParallelTo(IPlanarObject obj)
method IsNotParallelTo (line 216) | public bool IsNotParallelTo(IPlanarObject obj)
method IsOrthogonalTo (line 224) | public bool IsOrthogonalTo(IPlanarObject obj)
method IsCoplanarTo (line 232) | public bool IsCoplanarTo(IPlanarObject obj)
method IsCoplanarTo (line 240) | public bool IsCoplanarTo(ILinearObject obj)
method DistanceTo (line 250) | public double DistanceTo(Point3d p)
method DistanceSquared (line 255) | public double DistanceSquared(Point3d p)
method ClosestPoint (line 263) | public Point3d ClosestPoint(Point3d p)
method DistanceTo (line 289) | public double DistanceTo(Plane3d s)
method DistanceTo (line 307) | public double DistanceTo(Line3d l)
method DistanceTo (line 323) | public double DistanceTo(Segment3d s)
method DistanceTo (line 331) | public double DistanceTo(Segment3d s, out Point3d point_on_this_segmen...
method _DistanceTo (line 342) | internal double _DistanceTo(Segment3d s, out double p1, out double p2)
method DistanceTo (line 469) | public double DistanceTo(Ray3d r)
method DistanceTo (line 512) | public double DistanceTo(Circle3d c)
method DistanceTo (line 520) | public double DistanceTo(Sphere s)
method DistanceTo (line 531) | public double DistanceTo(Circle3d c, out Point3d point_on_segment, out...
method DistanceTo (line 539) | public double DistanceTo(Triangle t)
method DistanceTo (line 547) | public double DistanceTo(Triangle t, out Point3d point_on_segment, out...
method DistanceTo (line 555) | public double DistanceTo(ConvexPolyhedron cp)
method DistanceTo (line 563) | public double DistanceTo(ConvexPolyhedron cp, out Point3d point_on_seg...
method BelongsTo (line 574) | public bool BelongsTo(Line3d l)
method BoundingBox (line 612) | public Box3d BoundingBox(Coord3d coord = null)
method IntersectionWith (line 642) | public object IntersectionWith(Plane3d s)
method IntersectionWith (line 677) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 698) | public object IntersectionWith(Segment3d s)
method IntersectionWith (line 759) | public object IntersectionWith(Sphere s)
method IntersectionWith (line 768) | public object IntersectionWith(Ellipsoid e)
method IntersectionWith (line 777) | public object IntersectionWith(Ellipse e)
method IntersectionWith (line 786) | public object IntersectionWith(Circle3d c)
method IntersectionWith (line 795) | public object IntersectionWith(Ray3d r)
method IntersectionWith (line 804) | public object IntersectionWith(Triangle t)
method IntersectionWith (line 813) | public object IntersectionWith(Box3d b)
method Intersects (line 821) | public bool Intersects(Circle3d c)
method Intersects (line 830) | public bool Intersects(ConvexPolyhedron c)
method ProjectionTo (line 839) | public object ProjectionTo(Line3d l)
method ProjectionTo (line 856) | public object ProjectionTo(Plane3d s)
method _PointLocation (line 869) | internal override int _PointLocation(Point3d p)
method _AxialPointLocation (line 895) | internal int _AxialPointLocation(Point3d p)
method AngleTo (line 941) | public double AngleTo(ILinearObject obj)
method AngleToDeg (line 948) | public double AngleToDeg(ILinearObject obj)
method AngleTo (line 956) | public double AngleTo(IPlanarObject obj)
method AngleToDeg (line 963) | public double AngleToDeg(IPlanarObject obj)
method Translate (line 973) | public Segment3d Translate(Vector3d v)
method Rotate (line 981) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 990) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 999) | public virtual Segment3d Rotate(Rotation r, Point3d p)
method ReflectIn (line 1007) | public virtual Segment3d ReflectIn(Point3d p)
method ReflectIn (line 1015) | public virtual Segment3d ReflectIn(Line3d l)
method ReflectIn (line 1023) | public virtual Segment3d ReflectIn(Plane3d s)
method Scale (line 1031) | public virtual Segment3d Scale(double scale, Point3d scaling_center)
method Scale (line 1041) | public virtual Segment3d Scale(double scale)
method Equals (line 1053) | public override bool Equals(object obj)
method GetHashCode (line 1079) | public override int GetHashCode()
method ToString (line 1087) | public override String ToString()
method ToString (line 1095) | public String ToString(Coord3d coord)
FILE: GeometRi/Sphere.cs
class Sphere (line 9) | #if NET20_OR_GREATER
method Sphere (line 21) | public Sphere(Point3d P, double R)
method Copy (line 30) | public Sphere Copy()
method DistanceTo (line 96) | public double DistanceTo(Point3d p)
method DistanceTo (line 112) | public double DistanceTo(Line3d l)
method DistanceTo (line 128) | public double DistanceTo(Ray3d r)
method DistanceTo (line 137) | public double DistanceTo(Segment3d s)
method DistanceTo (line 146) | public double DistanceTo(Plane3d s)
method DistanceTo (line 162) | public double DistanceTo(Circle3d c)
method DistanceTo (line 174) | public double DistanceTo(Circle3d c, out Point3d p1, out Point3d p2)
method DistanceTo (line 183) | public double DistanceTo(Sphere s)
method DistanceTo (line 204) | public double DistanceTo(Sphere s, out Point3d p1, out Point3d p2)
method DistanceTo (line 232) | public double DistanceTo(Box3d box)
method DistanceTo (line 240) | public double DistanceTo(ConvexPolyhedron cp)
method BoundingBox (line 259) | public Box3d BoundingBox(Coord3d coord = null)
method AABB (line 268) | public AABB AABB()
method IsInside (line 285) | public bool IsInside(Box3d box)
method ClosestPoint (line 317) | public Point3d ClosestPoint(Point3d p)
method IntersectionWith (line 335) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 375) | public object IntersectionWith(Segment3d s)
method IntersectionWith (line 420) | public object IntersectionWith(Ray3d r)
method IntersectionWith (line 465) | public object IntersectionWith(Plane3d s)
method IntersectionWith (line 512) | public object IntersectionWith(Sphere s)
method Intersects (line 572) | public bool Intersects(Circle3d c)
method Intersects (line 580) | public bool Intersects(Triangle t)
method ProjectionTo (line 588) | public Circle3d ProjectionTo(Plane3d s)
method ProjectionTo (line 597) | public Segment3d ProjectionTo(Line3d l)
method _PointLocation (line 603) | internal override int _PointLocation(Point3d p)
method Translate (line 640) | public Sphere Translate(Vector3d v)
method Rotate (line 648) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 657) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 666) | public Sphere Rotate(Rotation r, Point3d p)
method ReflectIn (line 674) | public Sphere ReflectIn(Point3d p)
method ReflectIn (line 682) | public Sphere ReflectIn(Line3d l)
method ReflectIn (line 690) | public Sphere ReflectIn(Plane3d s)
method Scale (line 698) | public virtual Sphere Scale(double scale, Point3d scaling_center)
method Equals (line 708) | public override bool Equals(object obj)
method GetHashCode (line 730) | public override int GetHashCode()
method ToString (line 738) | public override String ToString()
method ToString (line 746) | public String ToString(Coord3d coord)
FILE: GeometRi/Tetrahedron.cs
class Tetrahedron (line 11) | #if NET20_OR_GREATER
method Tetrahedron (line 29) | public Tetrahedron()
method Tetrahedron (line 41) | public Tetrahedron(Point3d v1, Point3d v2, Point3d v3, Point3d v4)
method Random (line 53) | static public Tetrahedron Random()
method FromConvexPolyhedron (line 66) | static public Tetrahedron FromConvexPolyhedron(ConvexPolyhedron cp)
method Copy (line 82) | public Tetrahedron Copy()
method BoundingBox (line 243) | public Box3d BoundingBox(Coord3d coord = null)
method AABB (line 251) | public AABB AABB()
method DistanceTo (line 278) | public double DistanceTo(Point3d p)
method ClosestPoint (line 286) | public Point3d ClosestPoint(Point3d p)
method DistanceTo (line 311) | public double DistanceTo(Tetrahedron t)
method Intersects (line 361) | public bool Intersects(Tetrahedron t)
method IntersectsFast (line 384) | public bool IntersectsFast(Tetrahedron t)
method Intersects (line 397) | public bool Intersects(Triangle t)
method Intersects (line 415) | public bool Intersects(Line3d l)
method Intersects (line 427) | public bool Intersects(Ray3d r)
method Intersects (line 439) | public bool Intersects(Segment3d s)
method Intersects (line 455) | public bool Intersects(Box3d box)
method Intersects (line 471) | public bool Intersects(Sphere s)
method IntersectionWith (line 488) | public object IntersectionWith(Line3d l)
method _PointLocation (line 495) | internal override int _PointLocation(Point3d p)
method _SameSide (line 520) | internal int _SameSide(Point3d a, Point3d b, Point3d c, Point3d d, Poi...
method _WhichSide (line 538) | internal int _WhichSide(Tetrahedron tetra, Point3d p, Vector3d d)
method IsInside (line 573) | public bool IsInside(Box3d box)
method Translate (line 601) | public Tetrahedron Translate(Vector3d v)
method Rotate (line 609) | public Tetrahedron Rotate(Rotation r, Point3d p)
method ReflectIn (line 621) | public virtual Tetrahedron ReflectIn(Point3d p)
method ReflectIn (line 633) | public virtual Tetrahedron ReflectIn(Line3d l)
method ReflectIn (line 645) | public virtual Tetrahedron ReflectIn(Plane3d s)
method Scale (line 657) | public virtual Tetrahedron Scale(double scale)
method Scale (line 670) | public virtual Tetrahedron Scale(double scale, Point3d scaling_center)
method Scale (line 682) | public virtual Tetrahedron Scale(double scale_x, double scale_y, doubl...
method Equals (line 697) | public override bool Equals(object obj)
method GetHashCode (line 737) | public override int GetHashCode()
method ToString (line 745) | public override string ToString()
method ToString (line 753) | public string ToString(bool full_precision = false)
method ToString (line 761) | public string ToString(Coord3d coord, bool full_precision = false)
FILE: GeometRi/Triangle.cs
class Triangle (line 10) | #if NET20_OR_GREATER
method CheckFields (line 23) | private void CheckFields()
method ClearCache (line 33) | private void ClearCache()
method Triangle (line 51) | public Triangle(Point3d A, Point3d B, Point3d C)
method Copy (line 65) | public Triangle Copy()
method IsParallelTo (line 546) | public bool IsParallelTo(ILinearObject obj)
method IsNotParallelTo (line 554) | public bool IsNotParallelTo(ILinearObject obj)
method IsOrthogonalTo (line 562) | public bool IsOrthogonalTo(ILinearObject obj)
method IsParallelTo (line 570) | public bool IsParallelTo(IPlanarObject obj)
method IsNotParallelTo (line 578) | public bool IsNotParallelTo(IPlanarObject obj)
method IsOrthogonalTo (line 586) | public bool IsOrthogonalTo(IPlanarObject obj)
method IsCoplanarTo (line 594) | public bool IsCoplanarTo(IPlanarObject obj)
method IsCoplanarTo (line 602) | public bool IsCoplanarTo(ILinearObject obj)
method BoundingBox (line 648) | public Box3d BoundingBox(Coord3d coord = null)
method AABB (line 672) | public AABB AABB()
method DistanceTo (line 690) | public double DistanceTo(Point3d p)
method DistanceTo (line 698) | public double DistanceTo(Point3d p, out Point3d closest_point)
method DistanceSquared (line 763) | public double DistanceSquared(Point3d p)
method ClosestPoint (line 800) | public Point3d ClosestPoint(Point3d p)
method DistanceTo (line 809) | public double DistanceTo(Circle3d c)
method DistanceTo (line 821) | public double DistanceTo(Circle3d c, out Point3d point_on_triangle, ou...
method DistanceTo (line 832) | public double DistanceTo(ConvexPolyhedron c, out Point3d point_on_tria...
method DistanceTo (line 840) | public double DistanceTo(ConvexPolyhedron c)
method DistanceTo (line 848) | public double DistanceTo(Segment3d s)
method DistanceTo (line 883) | public double DistanceTo(Segment3d s, out Point3d point_on_triangle, o...
method DistanceTo (line 941) | public double DistanceTo(Triangle t)
method DistanceTo (line 952) | public double DistanceTo(Triangle t, out Point3d point_on_this_triangl...
method _DistanceToTriangle (line 963) | internal double _DistanceToTriangle(Triangle t)
method _DistanceToTriangle (line 1029) | internal double _DistanceToTriangle(Triangle t, out Point3d point_on_t...
method ProjectionTo (line 1119) | public Segment3d ProjectionTo(Line3d l)
method IntersectionWith (line 1147) | public object IntersectionWith(Line3d l)
method IntersectionWith (line 1198) | public object IntersectionWith(Plane3d s)
method _coplanar_IntersectionWith (line 1239) | internal object _coplanar_IntersectionWith(Line3d l)
method IntersectionWith (line 1338) | public object IntersectionWith(Segment3d s)
method IntersectionWith (line 1382) | public object IntersectionWith(Ray3d r)
method IntersectionWith_original (line 1402) | [Obsolete("this method is not optimzed. For better performance use Int...
method IntersectionWith_Moller (line 1439) | private object IntersectionWith_Moller(Ray3d ray)
method Intersects (line 1531) | public bool Intersects(Circle3d c)
method Intersects (line 1539) | public bool Intersects(Tetrahedron t)
method Intersects (line 1548) | public bool Intersects(ConvexPolyhedron c)
method Intersects (line 1556) | public bool Intersects(Sphere s)
method Intersects (line 1578) | public bool Intersects(Triangle t)
method Intersects (line 1611) | public bool Intersects(Box3d box)
method _PointLocation (line 1616) | internal override int _PointLocation(Point3d p)
method _InPlanePointLocation (line 1643) | internal int _InPlanePointLocation(Point3d p)
method AngleTo (line 1687) | public double AngleTo(ILinearObject obj)
method AngleToDeg (line 1694) | public double AngleToDeg(ILinearObject obj)
method AngleTo (line 1702) | public double AngleTo(IPlanarObject obj)
method AngleToDeg (line 1709) | public double AngleToDeg(IPlanarObject obj)
method Translate (line 1719) | public Triangle Translate(Vector3d v)
method Rotate (line 1727) | [System.Obsolete("use Rotation object and specify rotation center: thi...
method Rotate (line 1736) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r, Point3d...
method Rotate (line 1745) | public Triangle Rotate(Rotation r, Point3d p)
method ReflectIn (line 1753) | public Triangle ReflectIn(Point3d p)
method ReflectIn (line 1761) | public Triangle ReflectIn(Line3d l)
method ReflectIn (line 1769) | public Triangle ReflectIn(Plane3d s)
method Scale (line 1777) | public virtual Triangle Scale(double scale, Point3d scaling_center)
method Equals (line 1789) | public override bool Equals(object obj)
method GetHashCode (line 1820) | public override int GetHashCode()
method ToString (line 1828) | public override String ToString()
method ToString (line 1836) | public String ToString(Coord3d coord)
FILE: GeometRi/Vector3D.cs
class Vector3d (line 9) | #if NET20_OR_GREATER
method CheckFields (line 22) | private void CheckFields()
method ClearCache (line 30) | private void ClearCache()
method Vector3d (line 44) | public Vector3d(Coord3d coord = null)
method Vector3d (line 54) | public Vector3d(double X, double Y, double Z, Coord3d coord = null)
method Vector3d (line 63) | public Vector3d(Point3d p, Coord3d coord = null)
method Vector3d (line 83) | public Vector3d(Point3d p1, Point3d p2)
method Vector3d (line 98) | public Vector3d(double[] a, Coord3d coord = null)
method Random (line 113) | public static Vector3d Random()
method Copy (line 134) | public Vector3d Copy()
method IsParallelTo (line 249) | public bool IsParallelTo(ILinearObject obj)
method IsNotParallelTo (line 261) | public bool IsNotParallelTo(ILinearObject obj)
method IsOrthogonalTo (line 269) | public bool IsOrthogonalTo(ILinearObject obj)
method IsParallelTo (line 284) | public bool IsParallelTo(IPlanarObject obj)
method IsNotParallelTo (line 292) | public bool IsNotParallelTo(IPlanarObject obj)
method IsOrthogonalTo (line 300) | public bool IsOrthogonalTo(IPlanarObject obj)
method Normalize (line 335) | public void Normalize()
method Add (line 344) | public Vector3d Add(double a)
method Add (line 352) | public Vector3d Add(Vector3d v)
method Subtract (line 362) | public Vector3d Subtract(double a)
method Subtract (line 370) | public Vector3d Subtract(Vector3d v)
method Mult (line 381) | public Vector3d Mult(double a)
method Dot (line 394) | public double Dot(Vector3d v)
method Dot (line 400) | internal double Dot(Point3d v)
method Cross (line 419) | public Vector3d Cross(Vector3d v)
method ConvertTo (line 432) | public Vector3d ConvertTo(Coord3d coord)
method ConvertToGlobal (line 447) | public Vector3d ConvertToGlobal()
method AngleTo (line 466) | public double AngleTo(ILinearObject obj)
method AngleToDeg (line 473) | public double AngleToDeg(ILinearObject obj)
method AngleTo (line 481) | public double AngleTo(IPlanarObject obj)
method AngleToDeg (line 488) | public double AngleToDeg(IPlanarObject obj)
method ProjectionTo (line 497) | public Vector3d ProjectionTo(Vector3d v)
method Rotate (line 530) | [System.Obsolete("use Rotation object: this.Rotate(Rotation r)")]
method Rotate (line 539) | public Vector3d Rotate(Rotation r)
method ReflectIn (line 548) | public Vector3d ReflectIn(Point3d p)
method ReflectIn (line 556) | public Vector3d ReflectIn(Line3d l)
method ReflectIn (line 566) | public Vector3d ReflectIn(Plane3d s)
method Equals (line 577) | public override bool Equals(object obj)
method GetHashCode (line 601) | public override int GetHashCode()
method ToString (line 609) | public override String ToString()
method ToString (line 617) | public String ToString(Coord3d coord)
Condensed preview — 74 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,060K chars).
[
{
"path": ".gitattributes",
"chars": 2518,
"preview": "###############################################################################\n# Set default behavior to automatically "
},
{
"path": ".gitignore",
"chars": 3755,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
},
{
"path": "GeometRi/AABB.cs",
"chars": 31800,
"preview": "using System;\nusing static System.Math;\nusing System.Collections.Generic;\n\nnamespace GeometRi\n{\n /// <summary>\n /"
},
{
"path": "GeometRi/AbstractClass.cs",
"chars": 685,
"preview": "using System;\nusing static System.Math;\nusing System.Collections.Generic;\n\nnamespace GeometRi\n{\n\n#if NET20_OR_GREATER\n "
},
{
"path": "GeometRi/Box3d.cs",
"chars": 35474,
"preview": "using System;\nusing static System.Math;\nusing System.Collections.Generic;\n\nnamespace GeometRi\n{\n /// <summary>\n /"
},
{
"path": "GeometRi/Circle3D.cs",
"chars": 79460,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing static System.Math;\n\nnamespace GeometRi\n{\n "
},
{
"path": "GeometRi/ConvexPolyhedron.cs",
"chars": 93105,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Text;\n\nnamespace Ge"
},
{
"path": "GeometRi/Coord3D.cs",
"chars": 11026,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Cartesian coordinate system def"
},
{
"path": "GeometRi/Ellipse.cs",
"chars": 28476,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Ellipse in 3D space, defined by"
},
{
"path": "GeometRi/Ellipsoid.cs",
"chars": 43416,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Ellipsoid object defined by cen"
},
{
"path": "GeometRi/GeometRi.csproj",
"chars": 2626,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <TargetFrameworks>netstandard2.0;net461;netcoreapp3.1;net5.0</"
},
{
"path": "GeometRi/GeometRi3D.cs",
"chars": 8638,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Static class. Implements global"
},
{
"path": "GeometRi/Interface.cs",
"chars": 1105,
"preview": "using System;\n\nnamespace GeometRi\n{\n\n /// <summary>\n /// Interface for 1D objects (vector, line, ray, segment)\n "
},
{
"path": "GeometRi/Line3D.cs",
"chars": 17322,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Infinite line in 3D space and "
},
{
"path": "GeometRi/Matrix3D.cs",
"chars": 14992,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// General 3x3 matrix class.\n /"
},
{
"path": "GeometRi/Plane3D.cs",
"chars": 20261,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// 3D plane defined by point and a"
},
{
"path": "GeometRi/Point3D.cs",
"chars": 27160,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Point in 3D space defined in gl"
},
{
"path": "GeometRi/Quaternion.cs",
"chars": 15147,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Unit quaternion (W + X*i + Y*j "
},
{
"path": "GeometRi/Ray3D.cs",
"chars": 22013,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Ray in 3D space defined by poin"
},
{
"path": "GeometRi/Rotation.cs",
"chars": 30251,
"preview": "using System;\nusing static System.Math;\n\n\nnamespace GeometRi\n{\n /// <summary>\n /// Rotation in 3D space defined i"
},
{
"path": "GeometRi/Segment3D.cs",
"chars": 34964,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Line segment in 3D space define"
},
{
"path": "GeometRi/Sphere.cs",
"chars": 25148,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Sphere object defined by center"
},
{
"path": "GeometRi/Tetrahedron.cs",
"chars": 25255,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing static System.Math;\n\nnamespace GeometRi\n{\n "
},
{
"path": "GeometRi/Triangle.cs",
"chars": 62639,
"preview": "using System;\nusing System.Security;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Triangle"
},
{
"path": "GeometRi/Vector3D.cs",
"chars": 20069,
"preview": "using System;\nusing static System.Math;\n\nnamespace GeometRi\n{\n /// <summary>\n /// Vector in 3D space defined in g"
},
{
"path": "GeometRi.Benchmarks/GeometRi.Benchmarks.csproj",
"chars": 2445,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
},
{
"path": "GeometRi.Benchmarks/Program.cs",
"chars": 10554,
"preview": "using System;\nusing System.Diagnostics;\nusing System.Collections.Generic;\nusing GeometRi;\n\nnamespace GeometRi.Benchmark"
},
{
"path": "GeometRi.Benchmarks/Properties/AssemblyInfo.cs",
"chars": 1420,
"preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
},
{
"path": "GeometRi.Benchmarks/app.config",
"chars": 158,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Vers"
},
{
"path": "GeometRi.Example/GeometRi.Example.csproj",
"chars": 2298,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
},
{
"path": "GeometRi.Example/Program.cs",
"chars": 2199,
"preview": "using System;\nusing System.Runtime;\nusing GeometRi;\n\n\nnamespace GeometRi_Example\n{\n class Program\n {\n publ"
},
{
"path": "GeometRi.Example/Properties/AssemblyInfo.cs",
"chars": 1400,
"preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
},
{
"path": "GeometRi.Example/app.config",
"chars": 160,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Vers"
},
{
"path": "GeometRi.Example.FSharp/App.config",
"chars": 182,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n <startup> \n <supportedRuntime version=\"v4.0\" sku=\".N"
},
{
"path": "GeometRi.Example.FSharp/AssemblyInfo.fs",
"chars": 1495,
"preview": "namespace GeometRi.Example.FSharp.AssemblyInfo\n\nopen System.Reflection\nopen System.Runtime.CompilerServices\nopen System"
},
{
"path": "GeometRi.Example.FSharp/GeometRi.Example.FSharp.fsproj",
"chars": 3790,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microso"
},
{
"path": "GeometRi.Example.FSharp/Program.fs",
"chars": 9464,
"preview": "open GeometRi\nopen System\n\nlet sample1() = \n printfn \"Ptolemy's construction of a pentagon\"\n printfn \"Draw a regu"
},
{
"path": "GeometRi.Example.FSharp/packages.config",
"chars": 212,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n <package id=\"FSharp.Core\" version=\"4.5.2\" targetFramework=\"net461\" "
},
{
"path": "GeometRi.Tests/AABBTest.cs",
"chars": 3676,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/BoundingBoxTest.cs",
"chars": 3296,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/Box3dTest.cs",
"chars": 20278,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\nusing Syste"
},
{
"path": "GeometRi.Tests/CircleTest.cs",
"chars": 33881,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/ConvexPolyhedronTest.cs",
"chars": 36816,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/CoordTransformTest.cs",
"chars": 7350,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/CoplanarityTest.cs",
"chars": 3133,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/EllipseTest.cs",
"chars": 6715,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/EllipsoidTest.cs",
"chars": 15395,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/GeometRi.Tests.csproj",
"chars": 5538,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.micros"
},
{
"path": "GeometRi.Tests/Line3DTest.cs",
"chars": 4171,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/Matrix3dTest.cs",
"chars": 1427,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/NormalizeTest.cs",
"chars": 4351,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/OtherTest.cs",
"chars": 2924,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/Plane3dTest.cs",
"chars": 7340,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/Point3DTest.cs",
"chars": 7719,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/Properties/AssemblyInfo.cs",
"chars": 628,
"preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n[assembly: Assemb"
},
{
"path": "GeometRi.Tests/QuaternionTest.cs",
"chars": 628,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/Ray3DTest.cs",
"chars": 6213,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/ReflectTest.cs",
"chars": 2882,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/RelativeToleranceTest.cs",
"chars": 4312,
"preview": "using System;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\n\nnamespace GeometRi.Tests\n{\n [TestClass]\n publi"
},
{
"path": "GeometRi.Tests/RotateTest.cs",
"chars": 3425,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/RotationTest.cs",
"chars": 13370,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/Segment3dTest.cs",
"chars": 25483,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/SphereTest.cs",
"chars": 8754,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/TetrahedronTest.cs",
"chars": 14533,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/TranslateTest.cs",
"chars": 2537,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/TriangleIntersectionWithLineSegmentTests.cs",
"chars": 5914,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/TriangleTest.cs",
"chars": 35098,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/Vector3dTest.cs",
"chars": 2072,
"preview": "using System;\nusing static System.Math;\nusing Microsoft.VisualStudio.TestTools.UnitTesting;\nusing GeometRi;\n\nnamespace "
},
{
"path": "GeometRi.Tests/packages.config",
"chars": 222,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n <package id=\"MSTest.TestAdapter\" version=\"1.1.11\" targetFramework=\""
},
{
"path": "GeometRi.sln",
"chars": 3102,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.26430.14\nMin"
},
{
"path": "LICENSE.txt",
"chars": 1076,
"preview": "MIT License\n\nCopyright (c) 2017-2025 Sergey Tarasov\n\nPermission is hereby granted, free of charge, to any person obtaini"
},
{
"path": "README.md",
"chars": 33070,
"preview": "# GeometRi\n### Simple and lightweight computational geometry library for .Net\n\nMain purpose of the GeometRi library is m"
},
{
"path": "ReleaseNotes.md",
"chars": 4238,
"preview": "# GeometRi\n## Release notes\n\n### 1.5.0.8 (19/03/2026)\n* Fixed triangle-segment intersection.\n* Union of two AABB.\n* Smal"
},
{
"path": "ToDo.txt",
"chars": 87,
"preview": "Watertight Ray/Triangle Intersection:\nhttps://jcgt.org/published/0002/01/05/paper.pdf\n\n"
}
]
About this extraction
This page contains the full source code of the RiSearcher/GeometRi.CSharp GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 74 files (1000.7 KB), approximately 269.2k tokens, and a symbol index with 1231 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.