예제 #1
0
        public bool LocationToView(Location location, out PointF point)
        {
            // Move location to 3D earth
            var pos3d = new Vector4d(location.Position, 1);

            // Camera model
            var m = Matrix4d.Mult(modelViewMatrix, projectionMatrix);

            // Project into homogeneous 2D point
            var pos2h = Vector4d.Transform(pos3d, m);

            // Perform the perspective divide
            var pos2 = pos2h / pos2h.W;

            // Ignore points behind us
            if (pos2h.W < 0)
            {
                point = PointF.Empty;
                return(false);
            }

//			Console.WriteLine ("{0} = {1}", "W", pos2h.W);

            // Stretch into our view
            var fr = videoCameraView.Frame;

            point = new PointF(
                fr.X + (float)((pos2.X + 1) * 0.5) * fr.Width,
                fr.Y + (float)((-pos2.Y + 1) * 0.5) * fr.Height
                );
            return(true);
        }
예제 #2
0
        /// <summary>
        /// Bestimmt den geometrischen Fehler des angegebenen Vertex in Bezug auf die
        /// Fehlerquadrik Q.
        /// </summary>
        /// <param name="v">
        /// Der Vertex, dessen geometrischer Fehler bestimmt werden soll.
        /// </param>
        /// <param name="q">
        /// Die zugrundeliegende Fehlerquadrik.
        /// </param>
        /// <returns>
        /// Der geometrische Fehler an der Stelle des angegebenen Vertex.
        /// </returns>
        double ComputeVertexError(Vector3d v, Matrix4d q)
        {
            var h = new Vector4d(v, 1);

            // Geometrischer Fehler Δ(v) = vᵀQv.
            return(Vector4d.Dot(Vector4d.Transform(h, q), h));
        }
예제 #3
0
        private Vector3d WorldPointToDevPoint(Vector3d pt, double vw, double vh, Matrix4d modelV, Matrix4d projV)
        {
            Vector4d wv = pt.ToVector4d(1.0);

            Vector4d sv = Vector4d.Transform(wv, modelV);
            Vector4d pv = Vector4d.Transform(sv, projV);

            Vector4d dv;

            dv.X = pv.X / pv.W;
            dv.Y = pv.Y / pv.W;
            dv.Z = pv.Z / pv.W;
            dv.W = pv.W;

            double vw2 = vw / 2;
            double vh2 = vh / 2;

            dv.X *= vw2;
            dv.Y *= -vh2;

            dv.Z = 0;

            dv.X += vw2;
            dv.Y += vh2;

            return(dv.ToVector3d());
        }
예제 #4
0
        // operate on  display - can be called BY A THREAD
        public void GetSystemsInView(ref Vector3[] vert, ref int[] cols, int total, ref SortedDictionary <float, InViewInfo> list, TransFormInfo ti, int forcecol)
        {
            int    margin = -150;
            float  sqdist = 0F;
            double w2     = (double)ti.dwidth / 2.0;
            double h2     = (double)ti.dheight / 2.0;

            lock (lockdisplaydata)                                                  // must lock it..
            {
                for (int i = 0; i < total; i++)
                {
                    Vector3 v = vert[i];

                    Vector4d syspos = new Vector4d(v.X, v.Y, v.Z, 1.0);
                    Vector4d sysloc = Vector4d.Transform(syspos, ti.resmat);

                    if (sysloc.Z > ti.znear)
                    {
                        Vector2d syssloc = new Vector2d(((sysloc.X / sysloc.W) + 1.0) * w2, ((sysloc.Y / sysloc.W) + 1.0) * h2);

                        if ((syssloc.X >= margin && syssloc.X <= ti.dwidth - margin) && (syssloc.Y >= margin && syssloc.Y <= ti.dheight - margin))
                        {
                            sqdist = ((float)v.X - ti.campos.X) * ((float)v.X - ti.campos.X) + ((float)v.Y - ti.campos.Y) * ((float)v.Y - ti.campos.Y) + ((float)v.Z - ti.campos.Z) * ((float)v.Z - ti.campos.Z);

                            if (sqdist <= ti.sqlylimit)
                            {
                                list.Add(sqdist, new InViewInfo(new Vector3(v.X, v.Y, v.Z), (forcecol != 0) ? forcecol : cols[i]));
                            }
                        }
                    }
                }
            }
        }
예제 #5
0
파일: Glut.cs 프로젝트: kgfathur/nzy3d-api
        public static bool Project(Vector4d objPos, Matrix4d modelMatrix, Matrix4d projMatrix, double[] viewport, ref Vector4d winPos)
        {
            objPos.W = 1;

            Vector4d @out = default(Vector4d);

            @out = Vector4d.Transform(objPos, modelMatrix);
            @out = Vector4d.Transform(@out, projMatrix);

            if (@out.W == 0)
            {
                return(false);
            }

            @out.W = (1 / @out.W) * 0.5;

            // Map X/Y/Z to range 0-1
            @out.X = @out.X * @out.W + 0.5;
            @out.Y = @out.Y * @out.W + 0.5;
            @out.Z = @out.Z * @out.W + 0.5;

            // Map x, y to viewport
            winPos   = new Vector4d();
            winPos.X = @out.X * viewport[2] + viewport[0];
            winPos.Y = @out.Y * viewport[3] + viewport[1];
            winPos.Z = @out.Z;

            return(true);
        }
예제 #6
0
파일: Glut.cs 프로젝트: kgfathur/nzy3d-api
        public static bool UnProject(Vector4d winPos, Matrix4d modelMatrix, Matrix4d projMatrix, double[] viewport, ref Vector4d objPos)
        {
            Matrix4d p           = Matrix4d.Mult(modelMatrix, projMatrix);
            Matrix4d finalMatrix = Matrix4d.Invert(p);
            Vector4d @in         = winPos;

            // Map x and y from window coordinates
            @in.X = (@in.X - viewport[0]) / viewport[2];
            @in.Y = (@in.Y - viewport[1]) / viewport[3];
            // Map to range -1 to 1
            @in.X = @in.X * 2.0 - 1.0;
            @in.Y = @in.Y * 2.0 - 1.0;
            @in.Z = @in.Z * 2.0 - 1.0;
            @in.W = 1.0;
            Vector4d @out = Vector4d.Transform(@in, finalMatrix);

            if (@out.W == 0.0)
            {
                return(false);
            }

            @out.X /= @out.W;
            @out.Y /= @out.W;
            @out.Z /= @out.W;
            objPos  = @out;

            return(true);
        }
예제 #7
0
        private static bool Project(ref Vector3d world, ref Matrix4d modelviewMatrix, ref Matrix4d projectionMatrix, int[] viewport, out Vector3d screen)
        {
            Vector4d _in  = new Vector4d(world, 1.0);
            Vector4d _out = new Vector4d();

            Vector4d.Transform(ref _in, ref modelviewMatrix, out _out);
            Vector4d.Transform(ref _out, ref projectionMatrix, out _in);

            if (_in.W == 0.0)
            {
                screen = Vector3d.Zero;
                return(false);
            }

            _in.X /= _in.W;
            _in.Y /= _in.W;
            _in.Z /= _in.W;

            /* Map x, y and z to range 0-1 */
            _in.X = _in.X * 0.5 + 0.5;
            _in.Y = _in.Y * 0.5 + 0.5;
            _in.Z = _in.Z * 0.5 + 0.5;

            /* Map x,y to viewport */
            _in.X = _in.X * viewport[2] + viewport[0];
            _in.Y = _in.Y * viewport[3] + viewport[1];

            screen = new Vector3d(_in);
            return(true);
        }
예제 #8
0
        int like_gluUnProject(double winx, double winy, double winz, Matrix4d modelMatrix, Matrix4d projMatrix, int[] viewport, ref double objx, ref double objy, ref double objz)
        {
            Matrix4d finalMatrix;
            Vector4d _in;
            Vector4d _out;

            finalMatrix = Matrix4d.Mult(modelMatrix, projMatrix);
            finalMatrix.Invert();
            _in.X = winx;
            _in.Y = viewport[3] - winy;
            _in.Z = winz;
            _in.W = 1.0f;
            // Map x and y from window coordinates
            _in.X = (_in.X - viewport[0]) / viewport[2];
            _in.Y = (_in.Y - viewport[1]) / viewport[3];
            // Map to range -1 to 1
            _in.X = _in.X * 2 - 1;
            _in.Y = _in.Y * 2 - 1;
            _in.Z = _in.Z * 2 - 1;
            //__gluMultMatrixVecd(finalMatrix, _in, _out);
            // check if this works:
            _out = Vector4d.Transform(_in, finalMatrix);
            if (_out.W == 0.0)
            {
                return(0);
            }
            _out.X /= _out.W;
            _out.Y /= _out.W;
            _out.Z /= _out.W;
            objx    = _out.X;
            objy    = _out.Y;
            objz    = _out.Z;
            return(1);
        }
예제 #9
0
        /// <summary>Transform a Vector by the given Matrix</summary>
        /// <param name="vec">The vector to transform</param>
        /// <param name="mat">The desired transformation</param>
        /// <param name="result">The transformed vector</param>
        public static void Transform(ref Vector3d vec, ref Matrix4f mat, out Vector3d result)
        {
            Vector4d v4 = new Vector4d(vec.X, vec.Y, vec.Z, 1.0f);

            Vector4d.Transform(ref v4, ref mat, out v4);
            result = v4.XYZ;
        }
예제 #10
0
파일: TkHelper.cs 프로젝트: Nankk/Beastrack
        public static Vector2 Project(Vector3d vector)
        {
            // Add w element for conversion
            Vector4d v4 = new Vector4d(vector);

            v4.W = 1.0;

            // Get conversion matrices
            Matrix4d modelView;

            GL.GetDouble(GetPName.ModelviewMatrix, out modelView);
            Matrix4d projection;

            GL.GetDouble(GetPName.ProjectionMatrix, out projection);
            int[] vp = new int[4];
            GL.GetInteger(GetPName.Viewport, vp);
            Matrix4 viewport = Matrix4.Identity;

            // NOTE: Matrix4 type assumes the result obtained by "vector * matrix", instead of "matrix * vector".
            viewport.Row0.X = vp[2] / 2;
            viewport.Row1.Y = -vp[3] / 2;
            viewport.Row3.X = vp[2] / 2;
            viewport.Row3.Y = vp[3] / 2;

            // Convert to window coordinate system
            v4 = Vector4d.Transform(v4, modelView);
            v4 = Vector4d.Transform(v4, projection);
            v4 = Vector4d.Multiply(v4, 1.0 / v4.W);  // Manual normalization required
            v4 = (Vector4d)Vector4.Transform((Vector4)v4, viewport);

            // Return only x and y
            return(new Vector2((int)v4.X, (int)v4.Y));
        }
예제 #11
0
        // operate on  display
        public Vector3?FindPoint(ref Vector3[] vert, int total, int x, int y, ref double cursysdistz, TransFormInfo ti)
        {
            Vector3?ret = null;
            double  w2  = (double)ti.dwidth / 2.0;
            double  h2  = (double)ti.dheight / 2.0;

            for (int i = 0; i < total; i++)
            {
                Vector3 v = vert[i];

                Vector4d syspos = new Vector4d(v.X, v.Y, v.Z, 1.0);
                Vector4d sysloc = Vector4d.Transform(syspos, ti.resmat);

                if (sysloc.Z > ti.znear)
                {
                    Vector2d syssloc   = new Vector2d(((sysloc.X / sysloc.W) + 1.0) * w2 - x, ((sysloc.Y / sysloc.W) + 1.0) * h2 - y);
                    double   sysdistsq = syssloc.X * syssloc.X + syssloc.Y * syssloc.Y;

                    if (sysdistsq < 7.0 * 7.0)
                    {
                        double sysdist = Math.Sqrt(sysdistsq);

                        if ((sysdist + Math.Abs(sysloc.Z * ti.zoom)) < cursysdistz)
                        {
                            cursysdistz = sysdist + Math.Abs(sysloc.Z * ti.zoom);
                            ret         = new Vector3(v.X, v.Y, v.Z);
                        }
                    }
                }
            }

            return(ret);
        }
예제 #12
0
        public Ray Transfer(Vector3d objectPos, Vector3d lensPos)
        {
            Debug.Assert(Math.Abs(lensPos.Z) < epsilon);
            if (!IsPointWithinLens(lensPos))
            {
                return(null);
            }

            Vector4d transformedPos = Vector4d.Transform(
                (new Vector4d(objectPos) + Vector4d.UnitW),
                GetTransferMatrix(objectPos.Z));

            if (Math.Abs(transformedPos.W) > epsilon)
            {
                Vector4d.Divide(ref transformedPos, transformedPos.W, out transformedPos);
            }
            Vector3d outputDirection = transformedPos.Xyz;

            if (Math.Abs(transformedPos.W) > epsilon)
            {
                outputDirection -= lensPos;
            }
            if (Math.Abs(objectPos.Z) <= FocalLength)
            {
                // the image of the incoming ray origin was in the same
                // half-plane as the origin itself
                outputDirection = -outputDirection;
            }
            return(new Ray(lensPos, outputDirection));
        }
예제 #13
0
        /// <summary>Transform a Vector by the given Matrix</summary>
        /// <remarks>
        /// It is incorrect to call this method passing the same variable for
        /// <paramref name="result"/> as for <paramref name="left"/> or
        /// <paramref name="right"/>.
        /// </remarks>
        /// <param name="vec">The vector to transform</param>
        /// <param name="mat">The desired transformation</param>
        /// <param name="result">The transformed vector</param>
        public static void Transform(ref Vector3d vec, ref Matrix4d mat, out Vector3d result)
        {
            Vector4d v4 = new Vector4d(vec.X, vec.Y, vec.Z, 1.0);

            Vector4d.Transform(ref v4, ref mat, out v4);
            result.X = v4.X;
            result.Y = v4.Y;
            result.Z = v4.Z;
        }
예제 #14
0
        /// <summary>Transform a Vector3d by the given Matrix, and project the resulting Vector4d back to a Vector3d</summary>
        /// <param name="vec">The vector to transform</param>
        /// <param name="mat">The desired transformation</param>
        /// <param name="result">The transformed vector</param>
        public static void TransformPerspective(ref Vector3d vec, ref Matrix4d mat, out Vector3d result)
        {
            Vector4d v = new Vector4d(vec.X, vec.Y, vec.Z, 1);

            Vector4d.Transform(ref v, ref mat, out v);
            result.X = v.X / v.W;
            result.Y = v.Y / v.W;
            result.Z = v.Z / v.W;
        }
예제 #15
0
        /// <summary>
        /// Projects a 2d screenspace coordinate to world coordinates.
        /// </summary>
        public static Vector3d Unproject(Vector3d Point, Matrix4d View, Matrix4d Proj)
        {
            Matrix4d ma    = Matrix4d.Mult(View, Proj);
            Matrix4d ima   = Matrix4d.Invert(ma);
            Vector4d coord = new Vector4d(Point.X, Point.Y, Point.Z, 1.0);
            Vector4d res   = Vector4d.Transform(coord, ima);

            return(new Vector3d(res.X / res.W, res.Y / res.W, res.Z / res.W));
        }
예제 #16
0
        private static Vector3d UnProject(Vector3d screen, Matrix4d modelviewMatrix, Matrix4d projectionMatrix, int[] viewport)
        {
            Vector4d pos = Vector4d.Zero;

            pos.X = ((screen.X - (double)viewport[0]) / (double)viewport[2]) * 2.0 - 1.0;
            pos.Y = ((screen.Y - (double)viewport[1]) / (double)viewport[3]) * 2.0 - 1.0;
            pos.Z = (2.0 * screen.Z) - 1.0;
            pos.W = 1.0;

            Vector4d pos2 = Vector4d.Transform(pos, Matrix4d.Invert(Matrix4d.Mult(modelviewMatrix, projectionMatrix)));

            return(new Vector3d(pos2.X, pos2.Y, pos2.Z) / pos2.W);
        }
예제 #17
0
        public Ray3d GetMouseRay()
        {
            var start = new Vector4d((Window.Mouse.X / (double)Window.Width - 0.5) * 2.0, ((Window.Height - Window.Mouse.Y) / (double)Window.Height - 0.5) * 2.0, 0.0, 1.0);
            var end   = new Vector4d((Window.Mouse.X / (double)Window.Width - 0.5) * 2.0, ((Window.Height - Window.Mouse.Y) / (double)Window.Height - 0.5) * 2.0, -1.0, 1.0);

            var IPV = ProjectionMatrix.Inverted() * ViewMatrix.Inverted();

            start  = Vector4d.Transform(start, IPV);
            start /= start.W;
            end    = Vector4d.Transform(end, IPV);
            end   /= end.W;
            end   -= start;

            return(new Ray3d(new Vector3d(start.X, start.Y, start.Z), new Vector3d(end.X, end.Y, end.Z).Normalized()));
        }
예제 #18
0
        Vector3d point(double ang)
        {
            var maxr = Math.Max(MajorRadius, MinorRadius);
            var minr = Math.Min(MajorRadius, MinorRadius);

            MajorRadius = maxr;
            MinorRadius = minr;

            var mtr4    = Matrix4d.CreateFromAxisAngle(Normal, ang);
            var res     = Vector4d.Transform(new Vector4d(norm), mtr4);
            var realAng = Vector3d.CalculateAngle(res.Xyz, RefDir);
            var rad     = MajorRadius * MinorRadius / (Math.Sqrt(Math.Pow(MajorRadius * Math.Sin(realAng), 2) + Math.Pow(MinorRadius * Math.Cos(realAng), 2)));

            res *= rad;
            return(Location + res.Xyz);
        }
예제 #19
0
        void CameraRotation_Drag()
        {
            Transformation tf = new Transformation(
                (Transformation)DragInfo.StartInfo);

            Matrix4d m = tf.Matrixd * Matrix4d.Identity;

            m.Transpose();
            Vector4d y = Vector4d.Transform(new Vector4d(0, 1, 0, 0), m);

            tf.Translate(0, 0, -5);
            tf.RotateAxis(y.Xyz, -DragInfo.DeltaX * (float)Math.PI / 360);
            tf.RotateX(-DragInfo.DeltaY * (float)Math.PI / 360);
            tf.Translate(0, 0, 5);
            MainCamera.Tf = tf;
        }
예제 #20
0
        /// <summary>
        /// Unprojects the specified point on the screen with the specified depth
        /// to the 3D space.
        /// </summary>
        /// <param name="screenLocation">The point on the screen</param>
        /// <param name="depth">The depth value in the range [0, 1] (near to far)</param>
        /// <returns>The corresponding 3D point on the screen</returns>
        public static Vector3d UnProject(Point screenLocation, double depth)
        {
            int[]    viewport = GetViewportArray();
            Vector4d pos      = new Vector4d();

            // Map x and y from window coordinates, map to range -1 to 1
            pos.X = (screenLocation.X - viewport[0]) / (double)viewport[2] * 2.0f - 1.0f;
            pos.Y = 1 - (screenLocation.Y - viewport[1]) / (double)viewport[3] * 2.0f;
            pos.Z = depth * 2.0f - 1.0f;
            pos.W = 1.0f;

            Vector4d pos2    = Vector4d.Transform(pos, Matrix4d.Invert(GetModelViewMatrix() * GetProjectionMatrix()));
            Vector3d pos_out = new Vector3d(pos2.X, pos2.Y, pos2.Z);

            return(pos_out / pos2.W);
        }
예제 #21
0
        // https://gist.github.com/871099/8d37734ba22737c69173c2e44eaa332f9c85bcde
        // http://www.opentk.com/node/1892
        // http://www.opentk.com/node/1276
        // http://www.opentk.com/node/887
        // http://mesa3d.org/

        /// <summary>
        /// Projects a coordinate from world space into screen space.
        /// </summary>
        /// <param name="coordinate">The coordinate to project</param>
        /// <param name="viewport">The viewport dimensions</param>
        /// <param name="projection">The projection matrix</param>
        /// <param name="modelview">The modelview matrix</param>
        /// <returns>The coordinate in screen space.</returns>
        public static Coordinate Project(Coordinate coordinate, int[] viewport, Matrix4d projection, Matrix4d modelview)
        {
            var source = new Vector4d(coordinate.DX, coordinate.DY, coordinate.DZ, 1);
            var imed   = Vector4d.Transform(source, modelview);
            var vector = Vector4d.Transform(imed, projection);

            if (Math.Abs(vector.W - 0) < 0.00001)
            {
                return(null);
            }
            var result = Vector3d.Divide(vector.Xyz, vector.W);

            result.X = viewport[0] + viewport[2] * (result.X + 1) / 2;
            result.Y = viewport[1] + viewport[3] * (result.Y + 1) / 2;
            result.Z = (result.Z + 1) / 2;
            return(new Coordinate((decimal)result.X, (decimal)result.Y, (decimal)result.Z));
        }
예제 #22
0
        /// <summary>
        /// Converts a screen space point into a corresponding point in world space.
        /// </summary>
        /// <param name="coordinate">The coordinate to project</param>
        /// <param name="viewport">The viewport dimensions</param>
        /// <param name="projection">The projection matrix</param>
        /// <param name="modelview">The modelview matrix</param>
        /// <returns>The coordinate in world space.</returns>
        public static Coordinate Unproject(Coordinate coordinate, int[] viewport, Matrix4d projection, Matrix4d modelview)
        {
            var matrix = Matrix4d.Invert(Matrix4d.Mult(modelview, projection));
            var source = new Vector4d(
                (coordinate.DX - viewport[0]) * 2 / viewport[2] - 1,
                (coordinate.DY - viewport[1]) * 2 / viewport[3] - 1,
                2 * coordinate.DZ - 1,
                1);
            var vector = Vector4d.Transform(source, matrix);

            if (Math.Abs(vector.W - 0) < 0.00001)
            {
                return(null);
            }
            var result = Vector3d.Divide(vector.Xyz, vector.W);

            return(new Coordinate((decimal)result.X, (decimal)result.Y, (decimal)result.Z));
        }
예제 #23
0
        /// <summary>Gets the vector of where the mouse cursor currently is.</summary>
        /// <param name="projection"></param>
        /// <param name="modelView"></param>
        /// <param name="offsetX">will get the coords of the pixel to the right of the mouse cursor if true</param>
        /// <param name="offsetY">will get the coords of the pixel below the mouse cursor if true</param>
        private static Vector3d GetMousePosition(ref Matrix4d projection, ref Matrix4d modelView, bool offsetX, bool offsetY)
        {
            Matrix4d view;

            Matrix4d.Mult(ref modelView, ref projection, out view);
            int   x     = Settings.Game.Mouse.X + (offsetX ? 1 : 0);
            int   y     = Settings.Game.Height + (offsetY ? 1 : 0) - Settings.Game.Mouse.Y - 1;       //invert Y, window coords are opposite
            float depth = 0;

            GL.ReadPixels(x, y, 1, 1, PixelFormat.DepthComponent, PixelType.Float, ref depth);
            var viewPosition = new Vector4d
                               (
                (float)x / Settings.Game.Width * 2.0f - 1.0f,                   //map X to -1 to 1 range
                (float)y / Settings.Game.Height * 2.0f - 1.0f,                  //map Y to -1 to 1 range
                depth * 2.0f - 1.0f,                                            //map Z to -1 to 1 range
                1.0f
                               );
            var temp = Vector4d.Transform(viewPosition, Matrix4d.Invert(view));

            return(new Vector3d(temp.X, temp.Y, temp.Z) / temp.W);
        }
예제 #24
0
        static int gluUnProject4(double winx, double winy, double winz, double clipw, Matrix4d modelMatrix, Matrix4d projMatrix, int[] viewport, double near, double far, ref double objx,
                                 ref double objy, ref double objz, ref double objw)
        {
            Matrix4d finalMatrix;
            Vector4d _in;
            Vector4d _out;

            finalMatrix = Matrix4d.Mult(modelMatrix, projMatrix);

            //if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
            finalMatrix.Invert();

            _in.X = winx;
            _in.Y = winy;
            _in.Z = winz;
            _in.W = clipw;

            /* Map x and y from window coordinates */
            _in.X = (_in.X - viewport[0]) / viewport[2];
            _in.Y = (_in.Y - viewport[1]) / viewport[3];
            _in.Z = (_in.Z - near) / (far - near);

            /* Map to range -1 to 1 */
            _in.X = _in.X * 2 - 1;
            _in.Y = _in.Y * 2 - 1;
            _in.Z = _in.Z * 2 - 1;

            // TODO: check again (same order issue as prev. todos)
            _out = Vector4d.Transform(_in, finalMatrix);
            if (_out.W == 0.0)
            {
                return(0);
            }

            objx = _out.X;
            objy = _out.Y;
            objz = _out.Z;
            objw = _out.W;
            return(1);
        }
예제 #25
0
        public Vector3?FindOverSystem(int x, int y, out double cursysdistz, StarGrid.TransFormInfo ti)
        {
            cursysdistz = double.MaxValue;
            Vector3?ret = null;

            double w2 = (double)ti.dwidth / 2.0;
            double h2 = (double)ti.dheight / 2.0;

            lock (_starnames)                                   // lock so they can't add anything while we draw
            {
                foreach (StarNames sys in _starnames.Values)
                {
                    if (sys.paintstar != null)
                    {
                        Vector4d syspos = new Vector4d((float)sys.x, (float)sys.y, (float)sys.z, 1.0);
                        Vector4d sysloc = Vector4d.Transform(syspos, ti.resmat);

                        if (sysloc.Z > ti.znear)
                        {
                            Vector2d syssloc   = new Vector2d(((sysloc.X / sysloc.W) + 1.0) * w2 - x, ((sysloc.Y / sysloc.W) + 1.0) * h2 - y);
                            double   sysdistsq = syssloc.X * syssloc.X + syssloc.Y * syssloc.Y;

                            if (sysdistsq < 7.0 * 7.0)
                            {
                                double sysdist = Math.Sqrt(sysdistsq);

                                if ((sysdist + Math.Abs(sysloc.Z * ti.zoom)) < cursysdistz)
                                {
                                    cursysdistz = sysdist + Math.Abs(sysloc.Z * ti.zoom);
                                    ret         = new Vector3((float)sys.x, (float)sys.y, (float)sys.z);
                                }
                            }
                        }
                    }
                }
            }

            return(ret);
        }
예제 #26
0
        private static Vector4d UnProject(Matrix4d projection, Matrix4d view, Size viewport, Vector2d mouse)
        {
            Vector4d vec;

            vec.X = 2.0f * mouse.X / (float)viewport.Width - 1;
            vec.Y = -(2.0f * mouse.Y / (float)viewport.Height - 1);
            vec.Z = 0;
            vec.W = 1.0f;

            Matrix4d viewInv = Matrix4d.Invert(view);
            Matrix4d projInv = Matrix4d.Invert(projection);

            Vector4d.Transform(ref vec, ref projInv, out vec);
            Vector4d.Transform(ref vec, ref viewInv, out vec);

            if (vec.W > float.Epsilon || vec.W < float.Epsilon)
            {
                vec.X /= vec.W;
                vec.Y /= vec.W;
                vec.Z /= vec.W;
            }

            return(vec);
        }
예제 #27
0
        static int gluProject(double objx, double objy, double objz, Matrix4d modelMatrix, Matrix4d projMatrix, int[] viewport, ref double winx, ref double winy, ref double winz)
        {
            Vector4d _in;
            Vector4d _out;

            _in.X = objx;
            _in.Y = objy;
            _in.Z = objz;
            _in.W = 1.0;
            //__gluMultMatrixVecd(modelMatrix, in, out);
            //__gluMultMatrixVecd(projMatrix, out, in);
            //TODO: check if multiplication is in right order
            _out = Vector4d.Transform(_in, modelMatrix);
            _in  = Vector4d.Transform(_out, projMatrix);

            if (_in.W == 0.0)
            {
                return(0);
            }
            _in.X /= _in.W;
            _in.Y /= _in.W;
            _in.Z /= _in.W;
            /* Map x, y and z to range 0-1 */
            _in.X = _in.X * 0.5 + 0.5;
            _in.Y = _in.Y * 0.5 + 0.5;
            _in.Z = _in.Z * 0.5 + 0.5;

            /* Map x,y to viewport */
            _in.X = _in.X * viewport[2] + viewport[0];
            _in.Y = _in.Y * viewport[3] + viewport[1];

            winx = _in.X;
            winy = _in.Y;
            winz = _in.Z;
            return(1);
        }
예제 #28
0
        private ISystem GetMouseOverSystem(int x, int y)
        {
            Stopwatch sw = Stopwatch.StartNew();

            y = glControl.Height - y;
            if (y < 5)
            {
                y = 5;
            }
            else if (y > glControl.Height - 5)
            {
                y = glControl.Height - 5;
            }

            if (x < 5)
            {
                x = 5;
            }
            else if (x > glControl.Width - 5)
            {
                x = glControl.Width - 5;
            }

            double   w2 = glControl.Width / 2.0;
            double   h2 = glControl.Height / 2.0;
            Matrix4d proj;
            Matrix4d mview;

            GL.GetDouble(GetPName.ProjectionMatrix, out proj);
            GL.GetDouble(GetPName.ModelviewMatrix, out mview);
            Matrix4d resmat = Matrix4d.Mult(mview, proj);

            ISystem  cursys      = null;
            Vector4d cursysloc   = new Vector4d(0.0, 0.0, _zfar, 1.0);
            double   cursysdistz = double.MaxValue;

            foreach (var sys in _starList)
            {
                if (sys.HasCoordinate)
                {
                    Vector4d syspos = new Vector4d(sys.x, sys.y, sys.z, 1.0);
                    Vector4d sysloc = Vector4d.Transform(syspos, resmat);

                    if (sysloc.Z > _znear)
                    {
                        Vector2d syssloc = new Vector2d(((sysloc.X / sysloc.W) + 1.0) * w2 - x, ((sysloc.Y / sysloc.W) + 1.0) * h2 - y);
                        double   sysdist = Math.Sqrt(syssloc.X * syssloc.X + syssloc.Y * syssloc.Y);
                        if (sysdist < 7.0 && (sysdist + Math.Abs(sysloc.Z * _zoom)) < cursysdistz)
                        {
                            cursys      = sys;
                            cursysloc   = sysloc;
                            cursysdistz = sysdist + Math.Abs(sysloc.Z * _zoom);
                        }
                    }
                }
            }

            sw.Stop();
            var t = sw.ElapsedMilliseconds;

            return(cursys);
        }
예제 #29
0
 /// <summary>
 /// Transforms the given 4D vector by this Transform3D
 /// </summary>
 /// <param name="vector">The vector to be transformed</param>
 /// <returns>The transformed vector</returns>
 public Vector4d Transform(Vector4d vector)
 {
     return(Vector4d.Transform(vector, this.Value));
 }
예제 #30
0
        public override void Draw(IDrawingContext gr)
        {
            if (!Visible)
            {
                return;
            }
            GL.Color3(Color.Blue);
            if (Selected)
            {
                GL.Color3(Color.Red);
            }
            if (ShowGismos)
            {
                DrawHelpers.DrawCross(Location, DrawSize);
                PlaneSurface ps = new PlaneSurface()
                {
                    Position = Location, Normal = Axis
                };
                var             bs   = ps.GetBasis();
                var             dir  = bs[0] * Radius;
                List <Vector3d> pnts = new List <Vector3d>();
                var             step = Math.PI * AngleStep / 180f;
                for (double i = 0; i <= Math.PI * 2; i += step)
                {
                    var mtr4 = Matrix4d.CreateFromAxisAngle(Axis, i);
                    var res  = Vector4d.Transform(new Vector4d(dir), mtr4);
                    pnts.Add(Location + res.Xyz);
                }

                GL.Begin(PrimitiveType.LineStrip);
                for (int i = 0; i < pnts.Count; i++)
                {
                    GL.Vertex3(pnts[i]);
                }
                GL.End();
                pnts.Clear();

                for (double i = 0; i <= Math.PI * 2; i += step)
                {
                    var mtr4 = Matrix4d.CreateFromAxisAngle(Axis, i);
                    var res  = Vector4d.Transform(new Vector4d(dir), mtr4);
                    pnts.Add(Location + res.Xyz + Axis * Lenght);
                }

                GL.Begin(PrimitiveType.LineStrip);
                for (int i = 0; i < pnts.Count; i++)
                {
                    GL.Vertex3(pnts[i]);
                }
                GL.End();

                GL.Begin(PrimitiveType.Lines);
                GL.Vertex3(Location);
                GL.Vertex3(Location + Axis * Lenght);
                GL.End();
            }
            if (ShowMesh)
            {
                drawMesh();
            }
            drawContours();
        }