public static void RotateArbitrary(List <_3D_Point> L_Pts,
                                           _3D_Point v1,
                                           _3D_Point v2,
                                           float ang)
        {
            Transformation.TranslateX(L_Pts, v1.X * -1);
            Transformation.TranslateY(L_Pts, v1.Y * -1);
            Transformation.TranslateZ(L_Pts, v1.Z * -1);

            float dx = v2.X - v1.X;
            float dy = v2.Y - v1.Y;
            float dz = v2.Z - v1.Z;

            float theta = (float)Math.Atan2(dy, dx);
            float phi   = (float)Math.Atan2(Math.Sqrt(dx * dx + dy * dy), dz);

            theta = (float)(theta * 180 / Math.PI);
            phi   = (float)(phi * 180 / Math.PI);
            Transformation.RotatZ(L_Pts, theta * -1);
            Transformation.RotatY(L_Pts, phi * -1);

            Transformation.RotatZ(L_Pts, ang);

            Transformation.RotatY(L_Pts, phi * 1);
            Transformation.RotatZ(L_Pts, theta * 1);
            Transformation.TranslateZ(L_Pts, v1.Z * 1);
            Transformation.TranslateY(L_Pts, v1.Y * 1);
            Transformation.TranslateX(L_Pts, v1.X * 1);
        }
        public void RotateAroundEdge(int iWhichEdge, float th)
        {
            _3D_Point p1 = new _3D_Point(L_3D_Pts[L_Edges[iWhichEdge].i]);
            _3D_Point p2 = new _3D_Point(L_3D_Pts[L_Edges[iWhichEdge].j]);

            Transformation.RotateArbitrary(L_3D_Pts, p1, p2, th);
        }
 public static void TranslateZ(List <_3D_Point> L_Pts, float tz)
 {
     for (int i = 0; i < L_Pts.Count; i++)
     {
         _3D_Point p = L_Pts[i];
         p.Z += tz;
     }
 }
 public static void TranslateY(List <_3D_Point> L_Pts, float ty)
 {
     for (int i = 0; i < L_Pts.Count; i++)
     {
         _3D_Point p = L_Pts[i];
         p.Y += ty;
     }
 }
 public static void TranslateX(List <_3D_Point> L_Pts, float tx)
 {
     for (int i = 0; i < L_Pts.Count; i++)
     {
         _3D_Point p = L_Pts[i];
         p.X += tx;
     }
 }
예제 #6
0
        static public void Normalise(_3D_Point v)
        {
            float length;

            length = (float)Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z);
            v.X   /= length;
            v.Y   /= length;
            v.Z   /= length;
        }
예제 #7
0
        static public _3D_Point CrossProduct(_3D_Point p1, _3D_Point p2)
        {
            _3D_Point p3;

            p3   = new _3D_Point(0, 0, 0);
            p3.X = p1.Y * p2.Z - p1.Z * p2.Y;
            p3.Y = p1.Z * p2.X - p1.X * p2.Z;
            p3.Z = p1.X * p2.Y - p1.Y * p2.X;
            return(p3);
        }
        public Camera()
        {
            cop    = new _3D_Point(0, 0, -1250);   // new Point3D(0, -50, 0);
            lookAt = new _3D_Point(0, 0, 1);       //new Point3D(0, 50, 0);
            up     = new _3D_Point(0, 1, 0);


            front = 10; // 70.0;
            back  = 5200.0f;
            tanH  = (float)(Math.Tan(45 / 2 * Math.PI / 180));
            tanV  = (float)(Math.Tan(45 / 2 * Math.PI / 180));
        }
        public void TransformToOrigin_And_Rotate(_3D_Point a, _3D_Point e)
        {
            _3D_Point w = new _3D_Point(a.X, a.Y, a.Z);

            w.X -= cop.X;
            w.Y -= cop.Y;
            w.Z -= cop.Z;

            e.X = w.X * basisa.X + w.Y * basisa.Y + w.Z * basisa.Z;
            e.Y = w.X * basisc.X + w.Y * basisc.Y + w.Z * basisc.Z;
            e.Z = w.X * lookDir.X + w.Y * lookDir.Y + w.Z * lookDir.Z;
        }
        public bool ClipAgainstZ(_3D_Point a1, _3D_Point a2)
        {
            float t;

            if ((a1.Z <= front && a2.Z <= front) ||
                (a1.Z >= back && a2.Z >= back)
                )
            {
                return(false);
            }



            if ((a1.Z < front && a2.Z > front) ||
                (a1.Z > front && a2.Z < front))
            {
                t = (front - a1.Z) / (a2.Z - a1.Z);
                if (a1.Z < front)
                {
                    a1.X = a1.X + t * (a2.X - a1.X);
                    a1.Y = a1.Y + t * (a2.Y - a1.Y);
                    a1.Z = front;
                }
                else
                {
                    a2.X = a1.X + t * (a2.X - a1.X);
                    a2.Y = a1.Y + t * (a2.Y - a1.Y);
                    a2.Z = front;
                }
            }

            if ((a1.Z < back && a2.Z > back) ||
                (a1.Z > back && a2.Z < back))
            {
                t = (back - a1.Z) / (a2.Z - a1.Z);
                if (a1.Z < back)
                {
                    a2.X = a1.X + t * (a2.X - a1.X);
                    a2.Y = a1.Y + t * (a2.Y - a1.Y);
                    a2.Z = back;
                }
                else
                {
                    a1.X = a1.X + t * (a2.X - a1.X);
                    a1.Y = a1.Y + t * (a2.Y - a1.Y);
                    a1.Z = back;
                }
            }

            return(true);
        }
        public bool TransformToOrigin_And_Rotate_And_Project(_3D_Point w1, _3D_Point w2)
        {
            _3D_Point e1 = new _3D_Point(0, 0, 0);

            TransformToOrigin_And_Rotate(w1, e1);

            _3D_Point e2 = new _3D_Point(0, 0, 0);

            TransformToOrigin_And_Rotate(w2, e2);

            if (!ClipAgainstZ(e1, e2))
            {
                return(false);
            }

            _3D_Point n1 = new _3D_Point(0, 0, 0);

            n1.X = focal * e1.X / e1.Z;
            n1.Y = focal * e1.Y / e1.Z;
            n1.Z = focal;

            _3D_Point n2 = new _3D_Point(0, 0, 0);

            n2.X = focal * e2.X / e2.Z;
            n2.Y = focal * e2.Y / e2.Z;
            n2.Z = focal;

            NormalizeFov(n1);
            NormalizeFov(n2);

            if (!ClipAgainst_X_and_Y(n1, n2))
            {
                return(false);
            }

            // view mapping
            n1.X = (int)(ceneterX + cxScreen * n1.X / 2);
            n1.Y = (int)(ceneterY - cyScreen * n1.Y / 2);

            n2.X = (int)(ceneterX + cxScreen * n2.X / 2);
            n2.Y = (int)(ceneterY - cyScreen * n2.Y / 2);



            w1.X = n1.X;
            w1.Y = n1.Y;

            w2.X = n2.X;
            w2.Y = n2.Y;
            return(true);
        }
        //
        public static void TranslateX2(List <_3D_Point> L_Pts, List <Face> F, float tx)
        {
            for (int i = 0; i < L_Pts.Count; i++)
            {
                _3D_Point p = L_Pts[i];
                p.X += tx;
            }

            for (int i = 0; i < F.Count; i++)
            {
                _3D_Point p = F[i].facePoint;
                p.X += tx;
            }
        }
        public static void RotatX(List <_3D_Point> L_Pts, float theta)
        {
            float th = (float)(Math.PI * theta / 180);

            for (int i = 0; i < L_Pts.Count; i++)
            {
                _3D_Point p = L_Pts[i];

                float x_ = p.X;
                float y_ = (float)(p.Y * Math.Cos(th) - p.Z * Math.Sin(th));
                float z_ = (float)(p.Y * Math.Sin(th) + p.Z * Math.Cos(th));

                p.X = x_;
                p.Y = y_;
                p.Z = z_;
            }
        }
        public void BuildNewSystem()
        {
            lookDir = new _3D_Point(0, 0, 0);
            basisa  = new _3D_Point(0, 0, 0);
            basisc  = new _3D_Point(0, 0, 0);

            lookDir.X = lookAt.X - cop.X;
            lookDir.Y = lookAt.Y - cop.Y;
            lookDir.Z = lookAt.Z - cop.Z;
            Matrix.Normalise(lookDir);

            basisa = Matrix.CrossProduct(up, lookDir);
            Matrix.Normalise(basisa);

            basisc = Matrix.CrossProduct(lookDir, basisa);
            Matrix.Normalise(basisc);
        }
        public int getPoint(_3D_Point P)
        {
            for (int i = 0; i < L_3D_Pts.Count(); i++)
            {
                if (P == L_3D_Pts[i])
                {
                    return(i);
                }
            }

            for (int i = 0; i < L_3D_Pts.Count(); i++)
            {
                if ((int)P.X == (int)L_3D_Pts[i].X && (int)P.Y == (int)L_3D_Pts[i].Y && (int)P.Z == (int)L_3D_Pts[i].Z)
                {
                    return(i);
                }
            }
            return(0);
        }
        public bool isPointThere(_3D_Point P)
        {
            for (int i = 0; i < L_3D_Pts.Count(); i++)
            {
                if (P == L_3D_Pts[i])
                {
                    return(true);
                }
            }

            for (int i = 0; i < L_3D_Pts.Count(); i++)
            {
                if ((int)P.X == (int)L_3D_Pts[i].X && (int)P.Y == (int)L_3D_Pts[i].Y && (int)P.Z == (int)L_3D_Pts[i].Z)
                {
                    return(true);
                }
            }

            return(false);
        }
        void BuildOuter()
        {
            verticalSegments   = 20;
            horizontalSegments = N * 2;


            float incTheta = 180.0f / verticalSegments;
            float theta    = 90;

            for (int k = 0; k < verticalSegments; k++)
            {
                float dx = (float)Math.Cos(theta * Math.PI / 180) * radius;
                float dy = (float)Math.Sin(theta * Math.PI / 180) * radius;

                _3D_Point v = new _3D_Point(dx, dy, z);
                AddPoint(v);
                iP++;

                float incTheta2 = 360 / horizontalSegments;
                float theta2    = 0;
                for (int h = 0; h < horizontalSegments; h++)
                {
                    x = (float)Math.Cos(theta2 * Math.PI / 180) * dx;
                    z = (float)Math.Sin(theta2 * Math.PI / 180) * dx;

                    v = new _3D_Point(x, (float)dy, z);
                    AddPoint(v);

                    if (h > 0)
                    {
                        AddEdge(iP, iP - 1, Color.Yellow);
                    }
                    theta2 += incTheta2;
                    iP++;
                }

                theta += incTheta;
            }
        }
 public void AddPoint(_3D_Point pnn)
 {
     L_3D_Pts.Add(pnn);
 }
 public void NormalizeFov(_3D_Point p)
 {
     p.X /= tanH;
     p.Y /= tanV;
 }
        public bool ClipAgainst_X_and_Y(_3D_Point p1, _3D_Point p2)
        {
            float t;

            if ((p1.X >= 1 && p2.X >= 1) ||
                (p1.X <= -1 && p2.X <= -1)
                )
            {
                return(false);
            }


            if ((p1.X > 1 && p2.X < 1) || (p1.X < 1 && p2.X > 1))
            {
                t = (1 - p1.X) / (p2.X - p1.X);
                if (p1.X < 1)
                {
                    p2.Y = p1.Y + t * (p2.Y - p1.Y);
                    p2.X = 1;
                }
                else
                {
                    p1.Y = p1.Y + t * (p2.Y - p1.Y);
                    p1.X = 1;
                }
            }


            if ((p1.X < -1 && p2.X > -1) || (p1.X > -1 && p2.X < -1))
            {
                t = (-1 - p1.X) / (p2.X - p1.X);
                if (p1.X > -1)
                {
                    p2.Y = p1.Y + t * (p2.Y - p1.Y);
                    p2.X = -1;
                }
                else
                {
                    p1.Y = p1.Y + t * (p2.Y - p1.Y);
                    p1.X = -1;
                }
            }

            if ((p1.Y >= 1 && p2.Y >= 1) ||
                (p1.Y <= -1 && p2.Y <= -1))
            {
                return(false);
            }

            if ((p1.Y > 1 && p2.Y < 1) || (p1.Y < 1 && p2.Y > 1))
            {
                t = (1 - p1.Y) / (p2.Y - p1.Y);
                if (p1.Y < 1)
                {
                    p2.X = p1.X + t * (p2.X - p1.X);
                    p2.Y = 1;
                }
                else
                {
                    p1.X = p1.X + t * (p2.X - p1.X);
                    p1.Y = 1;
                }
            }

            if ((p1.Y < -1 && p2.Y > -1) || (p1.Y > -1 && p2.Y < -1))
            {
                t = (-1 - p1.Y) / (p2.Y - p1.Y);
                if (p1.Y > -1)
                {
                    p2.X = p1.X + t * (p2.X - p1.X);
                    p2.Y = -1;
                }
                else
                {
                    p1.X = p1.X + t * (p2.X - p1.X);
                    p1.Y = -1;
                }
            }

            return(true);
        }
 public _3D_Point(_3D_Point p)
 {
     X = p.X;
     Y = p.Y;
     Z = p.Z;
 }
        public void DrawYourSelf(Graphics g)
        {
            Font FF = new Font("System", 9);

            for (int k = 0; k < L_Edges.Count; k++)
            {
                int i = L_Edges[k].i;
                int j = L_Edges[k].j;

                _3D_Point pi = new _3D_Point(L_3D_Pts[i]);
                _3D_Point pj = new _3D_Point(L_3D_Pts[j]);

                _3D_Point PE1 = new _3D_Point(L_Edges[k].edgePoint);
                _3D_Point PE2 = new _3D_Point(0, 0, 0);

                bool isVisible  = cam.TransformToOrigin_And_Rotate_And_Project(pi, pj);
                bool isVisible2 = cam.TransformToOrigin_And_Rotate_And_Project(PE1, PE2);

                if (isVisible && L_Edges[k].visible)
                {
                    Pen Pn = new Pen(L_Edges[k].cl, 2);
                    g.DrawLine(Pn, pi.X, pi.Y, pj.X, pj.Y);
                    //draw edge number
                    //g.DrawString("E" + (k), FF, Brushes.Blue, (pi.X+pj.X)/2, (pi.Y+pj.Y)/2);


                    //drawing Point number
                    //g.DrawString("P" + (i), FF, Brushes.Green, pi.X, pi.Y);
                    //g.DrawString("P" + (j), FF, Brushes.Green, pj.X, pj.Y);

                    //drawing vertx points in red
                    if (L_3D_Pts[i].vertx)
                    {
                        g.FillEllipse(Brushes.Red, pi.X, pi.Y, 10, 10);
                    }

                    if (L_3D_Pts[j].vertx)
                    {
                        g.FillEllipse(Brushes.Red, pj.X, pj.Y, 10, 10);
                    }

                    //draw edge points
                    //g.FillEllipse(Brushes.Red, PE1.X, PE1.Y, 10, 10);
                }
            }
            //Draw faces in yellow
            if (selectedFace >= 0 && selectedFace < Faces.Count())
            {
                for (int k = 0; k < Faces[selectedFace].edges.Count(); k++)
                {
                    int i = L_Edges[Faces[selectedFace].edges[k]].i;
                    int j = L_Edges[Faces[selectedFace].edges[k]].j;

                    _3D_Point pi = new _3D_Point(L_3D_Pts[i]);
                    _3D_Point pj = new _3D_Point(L_3D_Pts[j]);


                    bool isVisible = cam.TransformToOrigin_And_Rotate_And_Project(pi, pj);
                    if (isVisible)
                    {
                        Pen Pn = new Pen(Color.Yellow, 5);
                        g.DrawLine(Pn, pi.X, pi.Y, pj.X, pj.Y);
                    }
                    g.DrawString("P" + (i), FF, Brushes.Green, pi.X, pi.Y);
                    g.DrawString("P" + (j), FF, Brushes.Green, pj.X, pj.Y);
                }
            }

            //draw blend region
            for (int p = 0; p < Faces.Count(); p++)
            {
                if (Faces[p].BlendRegion == true)
                {
                    for (int k = 0; k < Faces[p].edges.Count(); k++)
                    {
                        int i = L_Edges[Faces[p].edges[k]].i;
                        int j = L_Edges[Faces[p].edges[k]].j;

                        _3D_Point pi = new _3D_Point(L_3D_Pts[i]);
                        _3D_Point pj = new _3D_Point(L_3D_Pts[j]);


                        bool isVisible = cam.TransformToOrigin_And_Rotate_And_Project(pi, pj);
                        if (isVisible && L_Edges[Faces[p].edges[k]].visible)
                        {
                            Pen Pn = new Pen(Color.Crimson, 5);
                            g.DrawLine(Pn, pi.X, pi.Y, pj.X, pj.Y);
                        }
                    }
                }
            }
        }