Example #1
0
        static public Mesh createCylinder(double radius, double height, int circle_sections_count, Vector3D center, Vector3D Y_axis, double rev_rotate, bool is_back_face = false)
        {
            Points3D[] sections = new Points3D[2];

            double rad_per_point = 2 * Math.PI / circle_sections_count;


            for (int n_section = 0; n_section < sections.Length; ++n_section)
            {
                Points3D section = new Points3D();

                for (int i = 0; i < circle_sections_count; ++i)
                {
                    section.addPoint(new Vector3D(-Math.Cos(i * rad_per_point) * radius, 0, Math.Sin(i * rad_per_point) * radius));
                }

                section.rotate(new Vector3D(0, 1, 0), rev_rotate, Vector3D.zero);
                section.move(new Vector3D(0, n_section * height, 0));
                section.rotate(Matrix3x3.getRotationMatrixLookAtYAxis(new Vector3D(0, 1, 0), Y_axis), Vector3D.zero);
                section.move(center);
                sections[n_section] = section;
            }


            return(createFromLoopPoints3D(sections, true, false, is_back_face));
        }
        static void Main(string[] args)
        {
            Random random = new Random();

            Points2D[] points2D = new Points2D[10];
            for (int i = 0; i < 10; i++)
            {
                int x = random.Next(1, 10);
                int y = random.Next(1, 10);
                points2D[i] = new Points2D(x, y);
            }
            for (int i = 0; i < 10; i++)
            {
                double closestDistance = Math.Sqrt(200);
                int    closestPoint    = 0;
                for (int j = 0; j < 10; j++)
                {
                    if (j != i)
                    {
                        double distance = points2D[i].Distance2D(points2D[j]);
                        if (distance < closestDistance)
                        {
                            closestPoint    = j;
                            closestDistance = distance;
                        }
                    }
                }
                Console.WriteLine("closest point to point " + i + " " + points2D[i].Location2D() + " is point " + closestPoint + " " + points2D[closestPoint].Location2D() + ", the distance is " + closestDistance);
            }
            Console.WriteLine();
            Points3D[] points3D = new Points3D[10];
            for (int i = 0; i < 10; i++)
            {
                int x = random.Next(1, 10);
                int y = random.Next(1, 10);
                int z = random.Next(1, 10);
                points3D[i] = new Points3D(x, y, z);
            }
            for (int i = 0; i < 10; i++)
            {
                double closestDistance = Math.Sqrt(300);
                int    closestPoint    = 0;
                for (int j = 0; j < 10; j++)
                {
                    if (j != i)
                    {
                        double distance = points3D[i].Distance3D(points3D[j]);
                        if (distance < closestDistance)
                        {
                            closestPoint    = j;
                            closestDistance = distance;
                        }
                    }
                }
                Console.WriteLine("closest point to point " + i + " " + points3D[i].Location3D() + " is point " + closestPoint + " " + points3D[closestPoint].Location3D() + ", the distance is " + closestDistance);
            }
        }
Example #3
0
        public static double CalcutateDistance(Points3D firstPoint, Points3D secondPoint)
        {
            double distance = 0.0;

            distance = Math.Sqrt((firstPoint.X - secondPoint.X) * (firstPoint.X - secondPoint.X) +
                                 (firstPoint.Y - secondPoint.Y) * (firstPoint.Y - secondPoint.Y) +
                                 (firstPoint.Z - secondPoint.Z) * (firstPoint.Z - secondPoint.Z));

            return(distance);
        }
Example #4
0
        public static double Distance3D(Points3D firstPoint, Points3D secondPoint)
        {
            double distance = Math.Sqrt(
                Math.Pow(firstPoint.x3 - secondPoint.x3, 2) +
                Math.Pow(firstPoint.y3 - secondPoint.y3, 2) +
                Math.Pow(firstPoint.z3 - secondPoint.z3, 2)
                );

            return(distance);
        }
        private void InitializeChart()
        {
            tChart1.Aspect.Chart3DPercent = 75;
            tChart1.Aspect.Zoom           = 75;
            tChart1.Aspect.Orthogonal     = false;
            tChart1.Series.Add(point3D    = new Points3D());
            point3D.FillSampleValues();

            tChart1.Tools.Add(rotate = new Rotate());
            rotate.Inertia           = 80;
        }
Example #6
0
    void m_WheelModel_reinitialize()
    {
        m_wheel_mesh_sections_count = m_spokes_count * (m_wheel_mesh_additional_sections_count + 1);

        m_rim_base_sections = new Points3D[m_wheel_mesh_sections_count + 1];
        for (int i = 0; i < m_wheel_mesh_sections_count; ++i)
        {
            m_rim_base_sections[i] = new Points3D();
            m_rim_base_sections[i].addPoint(new Vector3D(0, -0.015, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(-0.008, -0.015, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(-0.008, -0.020, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(-0.010, -0.020, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(-0.010, -0.010, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(-0.005, 0, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(0.005, 0, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(0.010, -0.010, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(0.010, -0.020, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(0.008, -0.020, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(0.008, -0.015, 0));
            m_rim_base_sections[i].addPoint(new Vector3D(0, -0.015, 0));
        }

        int base_section_point_count = m_rim_base_sections[0].points_count;

        double[][] rough_wave_x    = new double [base_section_point_count][];
        double[][] rough_wave_y    = new double [base_section_point_count][];
        int        rough_min_range = (m_wheel_mesh_sections_count / m_spokes_count) * 3;
        int        rough_max_range = (m_wheel_mesh_sections_count / m_spokes_count) * 6;

        for (int i = 0; i < base_section_point_count; ++i)
        {
            rough_wave_x[i] = SplineInterpolator.generateRoughLoopedCurve(m_wheel_mesh_sections_count, rough_min_range, rough_max_range, m_rim_rough_size);
            rough_wave_y[i] = SplineInterpolator.generateRoughLoopedCurve(m_wheel_mesh_sections_count, rough_min_range, rough_max_range, m_rim_rough_size);
        }

        for (int i = 0; i < m_wheel_mesh_sections_count; ++i)
        {
            for (int j = 1; j < base_section_point_count - 1; ++j)   //exclude seam

            {
                m_rim_base_sections[i][j] += new Vector3D(rough_wave_x[j][i], rough_wave_y[j][i], 0);
            }
        }

        m_rim_base_sections[m_wheel_mesh_sections_count] = m_rim_base_sections[0].copy();

        m_WheelModel = new WheelModel(m_spokes_count, m_cross_count, m_rim_d, m_hub_d, m_axle_length, m_l_dish, m_r_dish);
        for (int i = 0; i < m_WheelModel.spokes_count; ++i)
        {
            m_WheelModel_spokes_rev90_offset[i] = UnityEngine.Random.Range(0, 4);
        }

        m_WheelModel_random_unbalance();
    }
Example #7
0
        static public Points3D createCircle_XZ_Points3D(double radius, int circle_sections_count)
        {
            Points3D section = new Points3D();

            double rad_per_point = 2 * Math.PI / circle_sections_count;

            for (int n_section = 0; n_section < circle_sections_count; ++n_section)
            {
                section.addPoint(new Vector3D(-Math.Cos(n_section * rad_per_point) * radius, 0, Math.Sin(n_section * rad_per_point) * radius));
            }

            return(section);
        }
Example #8
0
        public static Models.Path LoadPath(string filePath)
        {
            var path = new Models.Path();
            var sr   = new StreamReader(filePath);

            using (sr)
            {
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    Points3D point = Points3D.Parse(line);
                    path.AddPoint(point);
                }
            }

            return(path);
        }
Example #9
0
        private void SetACF()
        {
            int window = 50;

            var xArray = new double[window];
            var yArray = new double[window];
            var zArray = new double[window, window];

            var xBegin = (Width - window) / 2;

            if (xBegin < 0)
            {
                xBegin = 0;
            }
            var xEnd = xBegin + window;

            var yBegin = (Height - window) / 2;

            if (yBegin < 0)
            {
                yBegin = 0;
            }
            var yEnd = yBegin + window;

            var xMid = xBegin + (xEnd - xBegin) / 2;
            var yMid = xBegin + (yEnd - yBegin) / 2;

            var acfMax = GetACFValue(xMid, yMid, xMid, yMid, window);//GetACFValue(xxStart, yyStart, xxEnd, yyEnd, (xxEnd - xxStart) / 2, (yyEnd - yyStart) / 2);
            int indexY = 0;

            for (int y = yBegin; y < yEnd; y++)
            {
                int indexX = 0;
                for (int x = xBegin; x < xEnd; x++)
                {
                    var acf = GetACFValue(x, y, xMid, yMid, window);
                    var z   = acfMax == 0 ? 0 : acf / acfMax;

                    zArray[indexY, indexX++] = z;
                }
                yArray[indexY] = indexY;
                xArray[indexY] = indexY++;
            }

            ACF = new Points3D(xArray, yArray, zArray);
        }
Example #10
0
        static public Mesh createCircle(double radius, int circle_sections_count, Vector3D center, Vector3D Y_axis, bool is_back_face = false)
        {
            Mesh mesh = new Mesh();

            List <Vector3> vertices = new List <Vector3>();
            List <Vector2> uv       = new List <Vector2>();
            List <int>     indices  = new List <int>();

            double rad_per_point = 2 * Math.PI / circle_sections_count;

            vertices.Add(center.toVector3());
            uv.Add(new Vector2(0.5f, 0.5f));

            for (int i = 0; i < circle_sections_count; ++i)
            {
                Points3D section = new Points3D();

                uv.Add(new Vector2((float)(0.5 + Math.Cos(i * rad_per_point) / 2), (float)(0.5 - Math.Sin(i * rad_per_point) / 2)));


                section.addPoint(new Vector3D(-Math.Cos(i * rad_per_point) * radius, 0, Math.Sin(i * rad_per_point) * radius));

                section.rotate(Matrix3x3.getRotationMatrixLookAtYAxis(new Vector3D(0, 1, 0), Y_axis), Vector3D.zero);
                section.move(center);

                vertices.Add(section[0].toVector3());
            }

            for (int i = 0; i < circle_sections_count; ++i)
            {
                indices.AddRange(
                    new int[]
                {
                    0,
                    i + 1,
                    (i + 1) % (circle_sections_count) + 1
                }
                    );
            }
            mesh.vertices  = vertices.ToArray();
            mesh.uv        = uv.ToArray();
            mesh.triangles = indices.ToArray();
            mesh.RecalculateBounds();
            mesh.RecalculateNormals();
            return(mesh);
        }
Example #11
0
        static void Main()
        {
            Points3D point = new Points3D()
            {
                X = 1, Y = 2, Z = 3
            };

            Console.WriteLine(point);

            Console.WriteLine(Points3D.Origin);

            var dist = Point3DExtensions.CalcutateDistance(point, Points3D.Origin);

            Console.WriteLine(dist);

            var path = new Path();

            for (int i = 0; i < 10; i++)
            {
                path.AddPoint(new Points3D()
                {
                    X = i, Y = i * 2, Z = i + 3
                });
            }


            string pathStr = "../../path.txt";

            PathStorage.SavePath(path, pathStr);
            var pathFromFile = PathStorage.LoadPath(pathStr);

            foreach (var p in pathFromFile)
            {
                Console.WriteLine(p);
            }
        }
Example #12
0
    void m_WheelModel_compute_and_rebuild_mesh()
    {
        m_WheelModel.compute();

        m_WheelModel_left_side_disbalance  = m_WheelModel.getSpokeForceKgfSideDisbalance(false);
        m_WheelModel_right_side_disbalance = m_WheelModel.getSpokeForceKgfSideDisbalance(true);

        double total_disbalance = m_WheelModel_left_side_disbalance + m_WheelModel_right_side_disbalance;

        if (total_disbalance < m_WheelModel.spokes_count)
        {
            m_wheel_quality_Text.text  = "Идеальное";
            m_wheel_quality_Text.color = new Color(0, 0.8f, 0);
        }
        else
        if (total_disbalance < m_WheelModel.spokes_count * 2)
        {
            m_wheel_quality_Text.text  = "Хорошее";
            m_wheel_quality_Text.color = new Color(0.5f, 0.8f, 0);
        }
        else
        if (total_disbalance < m_WheelModel.spokes_count * 4)
        {
            m_wheel_quality_Text.text  = "Сойдёт";
            m_wheel_quality_Text.color = new Color(0.8f, 0.8f, 0);
        }
        else
        if (total_disbalance < m_WheelModel.spokes_count * 6)
        {
            m_wheel_quality_Text.text  = "Плохое";
            m_wheel_quality_Text.color = new Color(0.8f, 0.5f, 0);
        }
        else
        {
            m_wheel_quality_Text.text  = "Ужасное";
            m_wheel_quality_Text.color = new Color(0.8f, 0, 0);
        };

        /*
         * for (int i=0; i<m_WheelModel.spokes_count; ++i )
         * {
         *  Log.g.add( string.Format("{0} {1:0.00}", i, m_WheelModel.getSpokeForceKgf( i )) );
         * }*/

        double angle_per_section = 360.0 / m_wheel_mesh_sections_count;

        Points3D[] rim_sections = new Points3D[m_wheel_mesh_sections_count + 1];
        for (int i = 0; i < m_wheel_mesh_sections_count + 1; ++i)
        {
            Points3D rim_section = m_rim_base_sections[i].copy();

            Vector3D rim_center         = m_WheelModel.get_rim_center();
            Vector3D rim_point          = m_WheelModel.getRimPointByAngle(i * angle_per_section, 0, 0);
            Vector3D rim_bent_egg_point = m_WheelModel.getRimPointByAngle(i * angle_per_section, m_bent_on_every_100kgf, m_egg_on_every_100kgf);
            Vector3D Y = (rim_center - rim_point).normalized();
            Vector3D X = -m_WheelModel.get_rim_cross_axis();

            rim_section.rotate(Matrix3x3.fromVerticalVectors(X, Y, X.cross(Y).normalized()), Vector3D.zero);

            double angle = Vector3D.angleBetween(rim_bent_egg_point - rim_center, rim_point - rim_center);
            if (angle > Math.PI / 10000)
            {
                rim_section.rotate(Y.cross(X).normalized(), angle, Vector3D.zero);
            }

            rim_section.move(rim_bent_egg_point);

            rim_sections[i] = rim_section;
        }

        Mesh rim_mesh = MeshCreator.createFromPoints3D(rim_sections);

        Quaternion wheel_rotation = Quaternion.identity;

        if (m_wheel_GO != null)
        {
            wheel_rotation = m_wheel_GO.transform.rotation;
            Destroy(m_wheel_GO);
            m_wheel_GO = null;
        }

        if (m_wheel_spoke_wrench_GO != null)
        {
            Destroy(m_wheel_spoke_wrench_GO);
            m_wheel_spoke_wrench_GO = null;
        }

        m_wheel_GO       = new GameObject("wheel");
        m_wheel_GO.layer = layer_wheel;

        m_wheel_spoke_wrench_GO = Instantiate(m_spoke_wrench_prefab, m_wheel_GO.transform);

        MeshFilter mf = m_wheel_GO.AddComponent <MeshFilter>();

        mf.mesh = rim_mesh;
        MeshRenderer mr = m_wheel_GO.AddComponent <MeshRenderer>();

        mr.material = m_rim_mat;
        MeshCollider mc = m_wheel_GO.AddComponent <MeshCollider>();

        mc.sharedMesh = rim_mesh;

        if (m_wheel_box_GO != null)
        {
            Destroy(m_wheel_box_GO);
            m_wheel_box_GO = null;
        }
        m_wheel_box_GO       = new GameObject("wheel_box");
        m_wheel_box_GO.layer = layer_wheel_box;
        BoxCollider wheel_box_GO_BoxCollider = m_wheel_box_GO.AddComponent <BoxCollider>();

        wheel_box_GO_BoxCollider.center = mc.bounds.center;
        wheel_box_GO_BoxCollider.size   = mc.bounds.size;

        //hub
        Vector3D hub_l  = m_WheelModel.get_hub_pos() + new Vector3D(0, 0, 1) * m_WheelModel.axle_length / 2;
        Vector3D hub_r  = m_WheelModel.get_hub_pos() + new Vector3D(0, 0, -1) * m_WheelModel.axle_length / 2;
        Vector3D hub_lr = hub_r - hub_l;

        Mesh       hub_mesh = MeshCreator.createHub(hub_l, hub_lr.normalized(), 40, 0.005, 0.002 + m_WheelModel.hub_d / 2, m_WheelModel.axle_length, m_WheelModel.l_dish, m_WheelModel.r_dish, 0.005);
        GameObject hub_GO   = new GameObject("hub");

        hub_GO.transform.parent = m_wheel_GO.transform;
        hub_GO.AddComponent <MeshFilter>().mesh       = hub_mesh;
        hub_GO.AddComponent <MeshRenderer>().material = m_hub_mat;

        m_wheel_nipples_GO = new GameObject[m_WheelModel.spokes_count];

        for (int i = 0; i < m_WheelModel.spokes_count; ++i)
        {
            Vector3D hub_point  = m_WheelModel.get_hub_point(i);
            Vector3D nip_point  = m_WheelModel.getRimPointBySpoke(i, m_bent_on_every_100kgf, m_egg_on_every_100kgf);
            Vector3D rim_center = m_WheelModel.get_rim_center();
            Vector3D nip_hub    = hub_point - nip_point;

            // spokes
            Mesh spoke_mesh = MeshCreator.createCylinder(0.001, nip_hub.length(), 8, nip_point, nip_hub.normalized(), 0.0);

            GameObject spoke_GO = new GameObject("spoke");
            spoke_GO.transform.parent = m_wheel_GO.transform;
            spoke_GO.AddComponent <MeshFilter>().mesh       = spoke_mesh;
            spoke_GO.AddComponent <MeshRenderer>().material = m_spoke_mat;

            //nipple
            float nipple_rev_deg = (float)m_WheelModel.getNippleRotate(i) * m_WheelModel_force_modifier * Mathf.PI * 2 * Mathf.Rad2Deg;

            GameObject nipple_GO = Instantiate(m_nipple_prefab);
            nipple_GO.transform.parent        = spoke_GO.transform;
            nipple_GO.transform.localPosition = nip_point.toVector3();
            nipple_GO.transform.localRotation = Quaternion.LookRotation((hub_point - nip_point).normalized().toVector3(),
                                                                        m_WheelModel.get_rim_cross_axis().toVector3())
                                                *
                                                Quaternion.AngleAxis(nipple_rev_deg + m_WheelModel_spokes_rev90_offset[i] * 90, -Vector3.forward);
            m_wheel_nipples_GO[i] = nipple_GO;

            // eyelets
            Vector3D eyelet_center = nip_point;
            Vector3D eyelet_vector = m_WheelModel.get_rim_center() - eyelet_center;

            double eyelet_inner_dia               = 0.0038;
            double eyelet_outter_dia              = 0.0075;
            double eyelet_torus_circle_radius     = (eyelet_outter_dia - eyelet_inner_dia) / 4;
            int    eyelet_half_torus_points_count = 3;
            int    eyelet_section_count           = 12;

            Points3D[] eyelet_sections = new Points3D[eyelet_section_count];

            double torus_rad_per_section = 2 * Math.PI / (eyelet_section_count);

            for (int n_section = 0; n_section < eyelet_section_count; ++n_section)
            {
                Points3D eyelet_section      = new Points3D();
                double   torus_rad_per_point = Math.PI / (eyelet_half_torus_points_count - 1);
                for (int n_point = 0; n_point < eyelet_half_torus_points_count; ++n_point)
                {
                    eyelet_section.addPoint(
                        new Vector3D(Math.Cos(n_point * torus_rad_per_point) * eyelet_torus_circle_radius, Math.Sin(n_point * torus_rad_per_point) * eyelet_torus_circle_radius, 0)
                        );
                }
                eyelet_section.move(new Vector3D(-(eyelet_inner_dia / 2 + eyelet_torus_circle_radius), 0, 0));
                eyelet_section.rotate(new Vector3D(0, 1, 0), n_section * torus_rad_per_section, Vector3D.zero);
                eyelet_section.rotate(Matrix3x3.getRotationMatrixLookAtYAxis(new Vector3D(0, 0, 1), eyelet_vector.normalized()), Vector3D.zero);
                eyelet_section.move(eyelet_center);

                eyelet_sections[n_section] = eyelet_section;
            }
            Mesh eyelet_mesh = MeshCreator.createFromLoopPoints3D(eyelet_sections);

            GameObject eyelet_GO = new GameObject("eyelet");
            eyelet_GO.transform.parent = spoke_GO.transform;
            eyelet_GO.AddComponent <MeshFilter>().mesh       = eyelet_mesh;
            eyelet_GO.AddComponent <MeshRenderer>().material = m_eyelet_mat;

            Mesh       eyelet_low_circle_mesh = MeshCreator.createCircle(eyelet_inner_dia / 2 + eyelet_torus_circle_radius, eyelet_section_count, eyelet_center + eyelet_vector.normalized() * eyelet_torus_circle_radius / 2, eyelet_vector.normalized(), false);
            GameObject eyelet_low_circle_GO   = new GameObject("eyelet_low_circle");
            eyelet_low_circle_GO.transform.parent = eyelet_GO.transform;
            eyelet_low_circle_GO.AddComponent <MeshFilter>().mesh       = eyelet_low_circle_mesh;
            eyelet_low_circle_GO.AddComponent <MeshRenderer>().material = m_eyelet_circle_mat;
        }

        m_wheel_GO.transform.rotation = wheel_rotation;
        m_wheel_spoke_wrench_GO_updateTransformByCurrentSpoke();
    }
Example #13
0
        static public Mesh createHub(Vector3D l_axle_center, Vector3D dir, int circle_sections_count, double axle_radius, double hub_radius, double axle_length, double l_dish, double r_dish, double fl_thickness)
        {
            Mesh mesh = new Mesh();

            Points3D l_axle_circle_center = new Points3D(); l_axle_circle_center.addPoint(Vector3D.zero);

            Points3D l_axle_circle = createCircle_XZ_Points3D(axle_radius, circle_sections_count);
            //
            Points3D l_axle_l_dish_ll_circle = createCircle_XZ_Points3D(axle_radius, circle_sections_count);

            l_axle_l_dish_ll_circle.move(new Vector3D(0, l_dish - fl_thickness / 2, 0));

            Points3D l_axle_l_dish_lh_circle = createCircle_XZ_Points3D(hub_radius, circle_sections_count);

            l_axle_l_dish_lh_circle.move(new Vector3D(0, l_dish - fl_thickness / 2, 0));

            Points3D l_axle_l_dish_rh_circle = createCircle_XZ_Points3D(hub_radius, circle_sections_count);

            l_axle_l_dish_rh_circle.move(new Vector3D(0, l_dish + fl_thickness / 2, 0));

            Points3D l_axle_l_dish_r_hl_circle = createCircle_XZ_Points3D(axle_radius + (hub_radius - axle_radius) * 0.1, circle_sections_count);

            l_axle_l_dish_r_hl_circle.move(new Vector3D(0, l_dish + fl_thickness / 2, 0));

            Points3D l_axle_l_dish_rl_circle = createCircle_XZ_Points3D(axle_radius, circle_sections_count);

            l_axle_l_dish_rl_circle.move(new Vector3D(0, l_dish + fl_thickness / 2, 0));
            //
            Points3D l_axle_r_dish_ll_circle = createCircle_XZ_Points3D(axle_radius, circle_sections_count);

            l_axle_r_dish_ll_circle.move(new Vector3D(0, axle_length - r_dish - fl_thickness / 2, 0));

            Points3D l_axle_r_dish_l_lh_circle = createCircle_XZ_Points3D(axle_radius + (hub_radius - axle_radius) * 0.1, circle_sections_count);

            l_axle_r_dish_l_lh_circle.move(new Vector3D(0, axle_length - r_dish - fl_thickness / 2, 0));

            Points3D l_axle_r_dish_lh_circle = createCircle_XZ_Points3D(hub_radius, circle_sections_count);

            l_axle_r_dish_lh_circle.move(new Vector3D(0, axle_length - r_dish - fl_thickness / 2, 0));

            Points3D l_axle_r_dish_rh_circle = createCircle_XZ_Points3D(hub_radius, circle_sections_count);

            l_axle_r_dish_rh_circle.move(new Vector3D(0, axle_length - r_dish + fl_thickness / 2, 0));

            Points3D l_axle_r_dish_rl_circle = createCircle_XZ_Points3D(axle_radius, circle_sections_count);

            l_axle_r_dish_rl_circle.move(new Vector3D(0, axle_length - r_dish + fl_thickness / 2, 0));
            //
            Points3D r_axle_circle = createCircle_XZ_Points3D(axle_radius, circle_sections_count);

            r_axle_circle.move(new Vector3D(0, axle_length, 0));

            Points3D r_axle_circle_center = new Points3D(); r_axle_circle_center.addPoint(new Vector3D(0, axle_length, 0));

            Points3D[] sections = new Points3D[14]
            {
                l_axle_circle_center,
                l_axle_circle,
                l_axle_l_dish_ll_circle,
                l_axle_l_dish_lh_circle,
                l_axle_l_dish_rh_circle,
                l_axle_l_dish_r_hl_circle,
                l_axle_l_dish_rl_circle,
                l_axle_r_dish_ll_circle,
                l_axle_r_dish_l_lh_circle,
                l_axle_r_dish_lh_circle,
                l_axle_r_dish_rh_circle,
                l_axle_r_dish_rl_circle,
                r_axle_circle,
                r_axle_circle_center
            };

            for (int i = 0; i < sections.Length; ++i)
            {
                sections[i].rotate(Matrix3x3.getRotationMatrixLookAtYAxis(new math.Vector3D(0, 1, 0), dir), Vector3D.zero);
                sections[i].move(l_axle_center);
            }

            return(createLatheFromPoints3D(sections));
        }
            public double Distance3D(Points3D p)
            {
                double distance = Math.Sqrt((Math.Pow((x - p.x), 2) + Math.Pow((y - p.y), 2) + Math.Pow((z - p.z), 2)));

                return(distance);
            }