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 143 144 145 146 147 148 149 |
#include <iostream> #include <cmath> #include <vector> #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 _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() { float const radius = 1.0f; std::vector<int> latitudeElements = {4, 6, 7, 9, 12, 13, 16}; // north hemisphere from top to middle std::vector<SpherePoint> sphereDataSet; if(latitudeElements.empty()) return 0; // Sphere elements initialising int totalElements = 1; for(auto const & elements: latitudeElements) { totalElements += elements; } totalElements *= 2; for(int i = 0; i < totalElements; ++i) { SpherePoint point(0.0f, 0.0f, 0.0f); sphereDataSet.push_back(point); } // 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. int refIndex = 0; // Top unit element coordinates sphereDataSet[0] = SpherePoint(0.0f, 0.0f, 1.0f); refIndex++; // Latitude distribution calculation with its elements for north hemisphere int const numLatitudes = latitudeElements.size(); float const arcAngle = 180.0f / (2 * numLatitudes + 1); float refAngle = 0.0f; for (int i = 0; i < numLatitudes; ++i) { LatitudePointDistribution(arcAngle, i+1, latitudeElements[i], refIndex, refAngle, sphereDataSet); if(i >= numLatitudes - 1) break; refAngle += RotationalAngleCalculation(latitudeElements[i], latitudeElements[i+1]); } // Coordinate calculations for south hemisphere excluding bottom unit element for (int i = --refIndex; i > 0; --i) { float const z = -sphereDataSet[i].z; // Reversing the z axis for mirror effect float const x = sphereDataSet[i].x; float const y = sphereDataSet[i].y; sphereDataSet[++refIndex] = SpherePoint(x, y, z); } // Bottom unit element 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 < totalElements; ++i) { std::cout << i+1 <<". (" << sphereDataSet[i].x << "," << sphereDataSet[i].y << "," << sphereDataSet[i].z << ")" << std::endl; } return 0; } //////////////////////////////////////////////////////////////////////////////// void LatitudePointDistribution ( 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 = cosf(_latitude * (_verticalAngle * degToRadian)); float const latitudeRadius = 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 ) { float const rotationalAngle = 180.0f * ((1.0f / _numUnitsOfPreviousLatitude) - (1.0f / _numUnitOfCurrentLatitude)); return rotationalAngle; } |