Last active
January 27, 2016 15:09
-
-
Save avasilkov/8132266273a7edefe6df to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef ARCPLACER_H | |
| #define ARCPLACER_H | |
| #include <math.h> | |
| #define loopy(i, n) for(unsigned int i = 0; i < n; i++) | |
| static inline float posMod(float a, float n){ | |
| return a - n * floor(a/n); | |
| } | |
| //-180 to 180 | |
| inline float normalizeAngle(float angle){ | |
| return posMod(angle + M_PI, pi2) - M_PI; | |
| } | |
| //-180 to 180 | |
| inline float angleDiff(float angleFrom, float angleTo){ | |
| return normalizeAngle(angleTo - angleFrom);//yep, in reverse order | |
| } | |
| struct Arc{ | |
| float& cAngle;//current | |
| float pAngle;//preferred | |
| float size; | |
| float hs;//half size | |
| Arc(float& _cAngle, float _pAngle, float _size): | |
| cAngle(_cAngle), pAngle(posMod(_pAngle, pi2)), size(_size), hs(_size*0.5f){ | |
| cAngle = pAngle; | |
| } | |
| inline float getStart(){ | |
| return cAngle - hs; | |
| } | |
| inline float getEnd(){ | |
| return cAngle + hs; | |
| } | |
| //http://mathforum.org/library/drmath/view/67287.html | |
| //CCW ORDER + //size less than 360!//pi2 and positive! | |
| inline bool overlaps(Arc& arc){ | |
| float thisStart = getStart(); | |
| float c = posMod(arc.getStart() - thisStart, pi2); | |
| return size > c || c > posMod(arc.getEnd() - thisStart, pi2); | |
| } | |
| inline void set(float _pAngle, float _size){ | |
| pAngle = posMod(_pAngle, pi2); | |
| cAngle = pAngle; | |
| size = _size; | |
| hs = size*0.5f; | |
| } | |
| }; | |
| struct ArcPlacer{ | |
| std::vector<Arc> arcs; | |
| ArcPlacer()=default; | |
| void add(float& angleDestRef, float preferredAngle, float arcSize); | |
| std::vector<int> getOverlapped(Arc& arc, int pos); | |
| ~ArcPlacer() = default; | |
| }; | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "arcplacer.h" | |
| #include <fstream> | |
| int main (int argc, char *argv[]) | |
| { | |
| std::ofstream data; | |
| data.open ("data.txt", std::ios::out | std::ios::trunc); | |
| ArcPlacer placer; | |
| std::vector<float> placedAngles; | |
| placedAngles.resize(20); | |
| float toRad = M_PI/180; | |
| placer.add(placedAngles[0], 0, 1*toRad); | |
| placer.add(placedAngles[1], 0, 1*toRad); | |
| placer.add(placedAngles[2], 0, 1*toRad); | |
| placer.add(placedAngles[3], M_PI, 20*toRad); | |
| placer.add(placedAngles[4], M_PI, 1*toRad); | |
| placer.add(placedAngles[5], M_PI, 1*toRad); | |
| placer.add(placedAngles[6], M_PI, 1*toRad); | |
| placer.add(placedAngles[7], 0, 1*toRad); | |
| placer.add(placedAngles[8], 0, 1*toRad); | |
| placer.add(placedAngles[9], 0, 1*toRad); | |
| placer.add(placedAngles[10], 0, 1*toRad); | |
| placer.add(placedAngles[11], 0, 20*toRad); | |
| placer.add(placedAngles[12], 0, 1*toRad); | |
| placer.add(placedAngles[13], 0, 1*toRad); | |
| placer.add(placedAngles[14], 0, 1*toRad); | |
| placer.add(placedAngles[15], 0, 1*toRad); | |
| loopy(i, placer.arcs.size()){ | |
| data<<placedAngles[i]<<"\n"; | |
| } | |
| data.close(); | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "arcplacer.h" | |
| void ArcPlacer::add ( float& angleDestRef, float preferredAngle, float arcSize ) { | |
| Arc arc(angleDestRef, preferredAngle, arcSize); | |
| std::vector<int> ovs = getOverlapped(arc, -1);//overlapped arcs | |
| if(ovs.size() == 0){ | |
| arcs.push_back(arc); | |
| return; | |
| } | |
| float dummy; | |
| Arc buffArc(dummy, 0.0f, 0.0f); | |
| int iterCount = 0; | |
| float refAngle = arc.cAngle; | |
| while(iterCount++ < 360){ | |
| float cAngle = normalizeAngle(arc.pAngle - refAngle); | |
| float size = arc.size; | |
| for(int i : ovs){ | |
| cAngle += normalizeAngle(arcs[i].pAngle - refAngle); | |
| size += arcs[i].size; | |
| } | |
| cAngle /= ovs.size() + 1.0f; | |
| cAngle += refAngle; | |
| cAngle = posMod(cAngle, pi2); | |
| refAngle = cAngle; | |
| buffArc.set(cAngle, size); | |
| std::vector<int> ovsBefore = std::move(ovs); | |
| ovs = getOverlapped(buffArc, -1); | |
| if(ovs.size() != ovsBefore.size()){ | |
| continue; | |
| } | |
| bool stopIter = true; | |
| loopy(i, ovs.size()){ | |
| if(ovs[i] != ovsBefore[i]){ | |
| stopIter = false; | |
| break; | |
| } | |
| } | |
| if(stopIter){ | |
| iterCount = 10000; | |
| break; | |
| } | |
| } | |
| arcs.push_back(arc); | |
| ovs.push_back(arcs.size() - 1); | |
| auto& _arcs = arcs; | |
| std::sort(ovs.begin(), ovs.end(), | |
| [buffArc, _arcs](const int a, const int b){ | |
| return angleDiff(buffArc.cAngle, _arcs[a].pAngle) < angleDiff(buffArc.cAngle, _arcs[b].pAngle); | |
| } | |
| ); | |
| float startAngle = buffArc.cAngle - buffArc.hs; | |
| loopy(i, ovs.size()){ | |
| Arc& _arc = arcs[ovs[i]]; | |
| startAngle += _arc.size; | |
| _arc.cAngle = startAngle - _arc.hs; | |
| } | |
| } | |
| std::vector< int > ArcPlacer::getOverlapped ( Arc& arc, int pos ) { | |
| std::vector<int> res; | |
| loopy(i, arcs.size()){ | |
| if(arc.overlaps(arcs[i]) && pos != i){ | |
| res.push_back(i); | |
| } | |
| } | |
| return res; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment