Old one, using 3 points u can't do too much. Most obvisious is to find "center of mass" if that would be triangle of infinite thin:
C++:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <mutex>
#include <vector>
#include <string>
#include <cstdio>
#include <stdexcept>
namespace format_helper
{
template <class Src>
inline Src cast(Src v)
{
return v;
}
inline const char *cast(const std::string& v)
{
return v.c_str();
}
};
template <typename... Ts>
inline std::string stringfmt (const std::string &fmt, Ts&&... vs)
{
using namespace format_helper;
char b;
//not counting the terminating null character.
size_t required = std::snprintf(&b, 0, fmt.c_str(), cast(std::forward<Ts>(vs))...);
std::string result;
result.resize(required, 0);
std::snprintf(const_cast<char*>(result.data()), required + 1, fmt.c_str(), cast(std::forward<Ts>(vs))...);
return result;
}
struct Point
{
float x;
float y;
float z;
//this assumed be start
Point vectorTo(const Point& end) const
{
return {end.x-x, end.y-y, end.z-z};
}
float len() const //magnitude
{
return std::sqrt(x * x + y * y + z * z);
}
Point& operator*(float s)
{
x *=s;
y *=s;
z *=s;
return *this;
}
Point& operator+(float s)
{
x +=s;
y +=s;
z +=s;
return *this;
}
Point& operator-(float s)
{
x -=s;
y -=s;
z -=s;
return *this;
}
Point& operator/(float s)
{
x /=s;
y /=s;
z /=s;
return *this;
}
Point& normalize()
{
const float s = 1.f/len();
x *=s;
y *=s;
z *=s;
return *this;
}
Point cross(const Point& rkVector) const
{
return {y * rkVector.z - z * rkVector.y, z * rkVector.x - x * rkVector.z, x * rkVector.y - y * rkVector.x};
}
friend std::ostream & operator << (std::ostream &out, const Point &c);
};
std::ostream & operator << (std::ostream &out, const Point &c)
{
out << "["<<c.x <<"; "<<c.y<<"; "<<c.z<<"]";
return out;
}
Point operator + (const Point& a, const Point& b)
{
return {a.x + b.x, a.y + b.y, a.z + b.z};
}
//dot product (if a & b are perpendicular, dot product is zero)
float operator * (const Point& a, const Point& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
const static Point A{0.f, 0.f, 0.f}; //SOL
const static Point B{ 67.5, -119.46875, 24.84375}; //Achenar
const static Point C{-33.65625 , 72.46875, -20.65625}; //Alioth
float min(float a, float b, float c)
{
return std::fmin(a, std::fmin(b,c));
}
float max(float a, float b, float c)
{
return std::fmax(a, std::fmax(b,c));
}
Point minp(const Point& a, const Point& b, const Point& c)
{
return {min(a.x, b.x, c.x), min(a.y, b.y, c.y), min(a.z, b.z, c.z)};
}
Point maxp(const Point& a, const Point& b, const Point& c)
{
return {max(a.x, b.x, c.x), max(a.y, b.y, c.y), max(a.z, b.z, c.z)};
}
Point fromInt(uint64_t x, uint64_t y, uint64_t z, float step,const Point& start)
{
return {x * step + start.x, y * step + start.y, z * step + start.z};
}
static void hexchar(unsigned char c, unsigned char &hex1, unsigned char &hex2)
{
hex1 = c / 16;
hex2 = c % 16;
hex1 += hex1 <= 9 ? '0' : 'A' - 10;
hex2 += hex2 <= 9 ? '0' : 'A' - 10;
}
std::string urlencode(const std::string& s)
{
std::vector<char> v;
v.reserve(s.size());
for (const char c : s)
{
if ((c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
c == '-' || c == '_' || c == '.' || c == '!' || c == '~' ||
c == '*' || c == '\'' || c == '(' || c == ')')
v.push_back(c);
else
if (c == ' ')
v.push_back('+');
else
{
v.push_back('%');
unsigned char d1, d2;
hexchar(c, d1, d2);
v.push_back(d1);
v.push_back(d2);
}
}
return std::string(v.cbegin(), v.cend());
}
std::string createEDSMLink(const Point& point)
{
const auto params{stringfmt("x=%0.4f&y=%0.4f&z=%0.4f&radius=20", point.x, point.y, point.z)};
return stringfmt("https://www.edsm.net/api-v1/sphere-systems?%s", params);
}
void findInnerCircleCenter()
{
//for 3 sources we can get coordinates of the center of the inner circle of the triangle
//http://www.math24.ru/%D0%B4%D0%B2%D1%83%D0%BC%D0%B5%D1%80%D0%BD%D0%B0%D1%8F-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0-%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82.html
const float a = B.vectorTo(C).len();
const float b = A.vectorTo(C).len();
const float c = A.vectorTo(B).len();
const float summ = a + b + c;
const float x = (a * A.x + b * B.x + c * C.x) / summ;
const float y = (a * A.y + b * B.y + c * C.y) / summ;
const float z = (a * A.z + b * B.z + c * C.z) / summ;
std::cout << createEDSMLink(Point{x,y,z}) << std::endl;
}
void findEquallyRemotePoint()
{
const auto AB{A.vectorTo(B)};
const auto AC{A.vectorTo(C)};
const auto normal{AB.cross(AC).normalize()}; //perpendicular to surface ABC
}
//if it would solid methal triangle ABC then...
void findMassCenter()
{
//http://www.pm298.ru/reshenie/fha0503.php
const auto summ {A+B+C};
const Point M{summ.x / 3.f, summ.y/3.f, summ.z/3.f};
std::cout << createEDSMLink(M) << std::endl;
}
int main()
{
findInnerCircleCenter();
//findMassCenter();
return 0;
}
Last edited: