Latitude Point Distribution
C++. This is for symmetrical distribution of points in each latitude on a sphere. As an input, different number of points for each latitude can be assigned.
Top and bottom coordinates, of course, are the easy ones. Here, basic principle is to divide the sphere into two hemispheres. After doing calculations for the north hemisphere, reversing z axis as a mirror effect would be enough for south hemisphere.
Latitude heights are calculated by radius*cos(latitude*arcAngle) and angle value is calculated by dividing 180 degrees by total number of arcs. Then, latitude radius is calculated by radius*sin(latitude*arcAngle) for determining (x,y) points where z axis is the height.
As a final step, point distribution algorithm with rotation will calculate the coordinates of sphere points on each latitude.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #include <iostream> #include <cmath> #include <vector> #include <numeric> #include <iomanip> struct SpherePoint { SpherePoint(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} float x, y, z; }; void LatitudePointDistribution ( float const _radius, float const _verticalAngle, int const _latitude, int const _numUnits, int & _refIndex, float const _refAngle, std::vector<SpherePoint> & _dataSet ); float RotationalAngleCalculation ( int const _numUnitsOfPreviousLatitude, int const _numUnitOfCurrentLatitude ); int main() { std::vector<int> latitudePoints = {4, 6, 7, 9, 12, 13, 16}; // north hemisphere from top to middle std::vector<SpherePoint> sphereDataSet; if(latitudePoints.empty()) return 0; // Sphere points initialising for top, bottom, and two hemispheres int const totalPoints = 2 * (1 + std::accumulate(latitudePoints.begin(), latitudePoints.end(), 0)); for(int i = 0; i < totalPoints; ++i) { sphereDataSet.push_back(SpherePoint(0.0f, 0.0f, 0.0f)); } // COORDINATE CALCULATIONS // // Firstly, calculations for north hemispere will be done. There are seven latitudes plus top unit itself. // Latitude heights are calculated by radius*cos(latitude*arcAngle) where radius is 1. // Angle value is calculated by dividing 180 degrees by total number of arcs. // Latitude radius is calculated by radius*sin(latitude*arcAngle) for determining (x,y) points. z axis is the height. // Then, point distribution algorithm will calculate the coordinates of sphere points on each latitude. float const radius = 1.0f; int refIndex = 0; // Top point coordinates sphereDataSet[0] = SpherePoint(0.0f, 0.0f, 1.0f); refIndex++; // Latitude distribution calculation with its points for north hemisphere int const numLatitudes = latitudePoints.size(); float const arcAngle = 180.0f / (2 * numLatitudes + 1); float refAngle = 0.0f; for (int i = 0; i < numLatitudes; ++i) { LatitudePointDistribution(radius, arcAngle, i+1, latitudePoints[i], refIndex, refAngle, sphereDataSet); if(i >= numLatitudes - 1) break; refAngle += RotationalAngleCalculation(latitudePoints[i], latitudePoints[i+1]); } // Coordinate calculations for south hemisphere excluding bottom point for (int i = --refIndex; i > 0; --i) { // Reversing the z axis for mirror effect sphereDataSet[++refIndex] = SpherePoint(sphereDataSet[i].x, sphereDataSet[i].y, -sphereDataSet[i].z); } // Bottom point coordinates refIndex++; sphereDataSet[refIndex] = SpherePoint(0.0f, 0.0f, -1.0f); // PRINTING RESULTS std::cout << "The Coordinates of Sphere Points \n" << std::endl; std::cout << std::fixed; std::cout << std::setprecision(4); for(int i = 0; i < totalPoints; ++i) { std::cout << i+1 <<". (" << sphereDataSet[i].x << "," << sphereDataSet[i].y << "," << sphereDataSet[i].z << ")" << std::endl; } return 0; } //////////////////////////////////////////////////////////////////////////////// void LatitudePointDistribution ( float const _radius, float const _verticalAngle, int const _latitude, int const _numUnits, int & _refIndex, float const _refAngle, std::vector<SpherePoint> & _dataSet ) { float const degToRadian = 0.0174533f; // (3.1416f / 180.0f) float const z = _radius * cosf(_latitude * (_verticalAngle * degToRadian)); float const latitudeRadius = _radius * sinf(_latitude * (_verticalAngle * degToRadian)); float const horizontalAngle = 360.0f / _numUnits; for (int i = 0; i < _numUnits; ++i) { float const x = latitudeRadius * cosf((i * horizontalAngle + _refAngle) * degToRadian); float const y = latitudeRadius * sinf((i * horizontalAngle + _refAngle) * degToRadian); _dataSet[i + _refIndex] = SpherePoint(x, y, z); } _refIndex += _numUnits; } //////////////////////////////////////////////////////////////////////////////// float RotationalAngleCalculation ( int const _numUnitsOfPreviousLatitude, int const _numUnitOfCurrentLatitude ) { // Rotational angle return 180.0f * ((1.0f / _numUnitsOfPreviousLatitude) - (1.0f / _numUnitOfCurrentLatitude)); } |