public static Matrix3D LookAt( this Point3D position, Point3D target, Vector3D up ) { var vector = (Vector3D)position - (Vector3D)target; vector.Normalize(); var vector2 = Vector3D.CrossProduct( up, vector ); vector2.Normalize(); var vector3 = Vector3D.CrossProduct( vector, vector2 ); var matrix = new Matrix3D(); matrix.M11 = vector2.X; matrix.M12 = vector3.X; matrix.M13 = vector.X; matrix.M14 = 0f; matrix.M21 = vector2.Y; matrix.M22 = vector3.Y; matrix.M23 = vector.Y; matrix.M24 = 0f; matrix.M31 = vector2.Z; matrix.M32 = vector3.Z; matrix.M33 = vector.Z; matrix.M34 = 0f; matrix.OffsetX = -Vector3D.DotProduct( vector2, (Vector3D)position ); matrix.OffsetY = -Vector3D.DotProduct( vector3, (Vector3D)position ); matrix.OffsetZ = -Vector3D.DotProduct( vector, (Vector3D)position ); matrix.M44 = 1f; return matrix; }
/// <summary> /// Determine if point is contained by frustum /// </summary> /// <param name="point">Point</param> /// <returns>Containment type</returns> public ContainmentType Contains( Point3D point ) { foreach ( Plane plane in planes ) { if ( plane.Distance( point ) < 1E-05f ) return ContainmentType.Disjoint; } return ContainmentType.Contains; }
internal Rect3D( Point3D point1, Point3D point2 ) { this._x = Math.Min( point1._x, point2._x ); this._y = Math.Min( point1._y, point2._y ); this._z = Math.Min( point1._z, point2._z ); this._sizeX = Math.Max( point1._x, point2._x ) - this._x; this._sizeY = Math.Max( point1._y, point2._y ) - this._y; this._sizeZ = Math.Max( point1._z, point2._z ) - this._z; }
public BSPImage( Point3D position, Uri source ) { // TODO: This hack is to ensure no point is zero. To fix this properly, fully define // cubes in the BSP tree and implement 'splitting' when they cross planes. this.position = new Point3D( position.X != 0 ? position.X : 0.001, position.Y != 0 ? position.Y : 0.001, position.Z != 0 ? position.Z : 0.001 ); this.source = source; }
/// <summary> /// Determine distance of point from frustum /// </summary> /// <param name="point">Point</param> /// <returns>Distance</returns> public double Distance( Point3D point ) { double maximum = 0; foreach ( Plane plane in planes ) { var distance = plane.Distance( point ); if ( distance < 0 ) maximum = Math.Max( maximum, -distance ); } return maximum; }
public Rect3D( Point3D location, Size3D size ) { if ( size.IsEmpty ) { this = s_empty; } else { this._x = location._x; this._y = location._y; this._z = location._z; this._sizeX = size._x; this._sizeY = size._y; this._sizeZ = size._z; } }
/// <summary> /// Constructor /// </summary> /// <param name="min">Minimum extent</param> /// <param name="max">Maximum extent</param> public BoundingBox( Point3D min, Point3D max ) { this.min = min; this.max = max; initialized = true; }
/// <summary> /// Classify point relative to plane /// </summary> /// <param name="point">Point</param> /// <returns>Intersection classification</returns> public Halfspace Classify( Point3D point ) { return Classify( Distance( point ) ); }
/// <summary> /// Calculate distance to point /// </summary> /// <param name="point">Point</param> /// <returns>Distance</returns> public double Distance( Point3D point ) { return normal.X * point.X + normal.Y * point.Y + normal.Z * point.Z + d; }
public static Point3D Multiply( Point3D point, Matrix3D matrix ) { return matrix.Transform( point ); }
internal static void Subtract( ref Point3D p1, ref Point3D p2, out Vector3D result ) { result._x = p1._x - p2._x; result._y = p1._y - p2._y; result._z = p1._z - p2._z; }
public static Vector3D Subtract( Point3D point1, Point3D point2 ) { Vector3D result = new Vector3D(); Subtract( ref point1, ref point2, out result ); return result; }
public static Point3D Subtract( Point3D point, Vector3D vector ) { return new Point3D( point._x - vector._x, point._y - vector._y, point._z - vector._z ); }
public static Point3D Add( Point3D point, Vector3D vector ) { return new Point3D( point._x + vector._x, point._y + vector._y, point._z + vector._z ); }
public static Point3D Add( Vector3D vector, Point3D point ) { return new Point3D( vector._x + point._x, vector._y + point._y, vector._z + point._z ); }
private ICollection<BSPImage> PreparePhotos( IEnumerable<string> urls ) { var items = new List<BSPImage>(); var count = urls.Count(); var size = (int)Math.Ceiling( Math.Pow( count, 1.0 / 3 ) ); // TODO: Properly split BSP items in tree if they cross planes; then don't need to force even-valued sizez if ( ( size & 1 ) == 1 ) ++size; var offset = -( ( (double)size - 1 ) / 2 ); var origin = new Vector3D( offset, offset, offset ); pending = 0; var positions = new Dictionary<string, string>(); var rand = new Random(); foreach ( var url in urls ) { Point3D point; string key; do { point = new Point3D( rand.Next( size ), rand.Next( size ), rand.Next( size ) ); key = point.X + "," + point.Y + "," + point.Z; } while ( positions.ContainsKey( key ) ); positions[ key ] = url; var image = new BSPImage( point + origin, new Uri( url ) ); image.Loaded += delegate { if ( Interlocked.Decrement( ref pending ) < 1 ) loading.Stop(); }; image.Failed += delegate { if ( Interlocked.Decrement( ref pending ) < 1 ) loading.Stop(); }; image.Click += ItemClick; image.WebClick += ItemWebClick; items.Add( image ); } pending = items.Count; return items; }
/// <summary> /// Get union of bounds /// </summary> /// <param name="bounds">Bounds</param> /// <returns>Union of bounds</returns> public void Merge( IEnumerable<Point3D> positions ) { foreach ( var p in positions ) { if ( !initialized ) { min = p; max = p; initialized = true; } else { if ( p.X < min.X ) min.X = p.X; if ( p.Y < min.Y ) min.Y = p.Y; if ( p.Z < min.Z ) min.Z = p.Z; if ( p.X > max.X ) max.X = p.X; if ( p.Y > max.Y ) max.Y = p.Y; if ( p.Z > max.Z ) max.Z = p.Z; } } }
internal Rect3D( Point3D point, Vector3D vector ) : this( point, point + vector ) { }
public bool Contains( Point3D point ) { return this.Contains( point._x, point._y, point._z ); }
public static Rect3D Union( Rect3D rect, Point3D point ) { rect.Union( new Rect3D( point, point ) ); return rect; }
public void Union( Point3D point ) { this.Union( new Rect3D( point, point ) ); }
public static Point3D Subtract( Vector3D vector, Point3D point ) { return new Point3D( vector._x - point._x, vector._y - point._y, vector._z - point._z ); }
public static bool Equals( Point3D point1, Point3D point2 ) { if ( point1.X.Equals( point2.X ) && point1.Y.Equals( point2.Y ) ) { return point1.Z.Equals( point2.Z ); } return false; }
private void Refresh( IEnumerable<BSPImage> items, Point3D viewpoint ) { refresh = false; if ( needsRefresh ) { if ( Width > 0 && Height > 0 ) camera.AspectRatio = Width / Height; needsRefresh = false; } var display = camera.CreateDisplayMatrix( Width, Height ); var maxDistance = 0.5; foreach ( var item in items ) { var distance = camera.GetFrustum().Distance( item.Position ); var visual = item.Visual; if ( distance <= maxDistance ) { visual.Opacity = 1 - ( distance / maxDistance ); Vector3D perp = Vector3D.CrossProduct( (Vector3D)item.Position, (Vector3D)viewpoint ); perp.Normalize(); var m = item.Transform; var translate = new Vector3D( m.OffsetX, m.OffsetY, m.OffsetZ ); var points = new Point3D[] { (Point3D)item.Position + translate, (Point3D)( item.Position + translate + perp ) }; display.Transform( ref points ); var halfWidth = ( points[ 1 ] - points[ 0 ] ).Length / 2; var transform = new TransformGroup(); transform.Children.Add( new TranslateTransform { X = -0.5, Y = -0.5 } ); transform.Children.Add( new RotateTransform { Angle = item.Angle2D } ); transform.Children.Add( new ScaleTransform { ScaleX = halfWidth * 2, ScaleY = halfWidth * 2 } ); transform.Children.Add( new TranslateTransform { X = points[ 0 ].X, Y = points[ 0 ].Y } ); visual.RenderTransform = transform; } else { visual.Opacity = 0; } visual.IsHitTestVisible = ( visual.Opacity > 0.05 ); } }
public bool Equals( Point3D value ) { return Equals( this, value ); }