Skip to content

Commit 314c921

Browse files
committed
Allow variations in latitude extent of Lunar mansions
1 parent 909d779 commit 314c921

File tree

2 files changed

+66
-18
lines changed

2 files changed

+66
-18
lines changed

src/core/StelSkyCultureSkyPartition.cpp

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
StelSkyCultureSkyPartition::StelSkyCultureSkyPartition(const QJsonObject &json):
3333
frameType(StelCore::FrameObservercentricEclipticOfDate),
3434
partitions(),
35-
extent(90.),
35+
extent(QList<double>{90.}),
3636
centerLine(nullptr),
3737
linkStars(),
3838
offset(0.0),
@@ -60,10 +60,18 @@ StelSkyCultureSkyPartition::StelSkyCultureSkyPartition(const QJsonObject &json):
6060
if (json.contains("context"))
6161
context = json["context"].toString();
6262

63-
// Parse extent, create polar caps where needed.
63+
// Parse extent: either one value defining north/south caps, or per-station limits.
6464
if (json.contains("extent") && json["extent"].isDouble())
6565
{
66-
extent=json["extent"].toDouble();
66+
extent.clear();
67+
extent.append(json["extent"].toDouble());
68+
}
69+
else if (json.contains("extent") && json["extent"].isArray())
70+
{
71+
extent.clear();
72+
QJsonArray ext=json["extent"].toArray();
73+
for (unsigned int i=0; i<ext.size(); ++i)
74+
extent.append(ext.at(i).toDouble());
6775
}
6876
else
6977
qWarning() << "Bad \"extent\" given in JSON file.";
@@ -209,7 +217,7 @@ void StelSkyCultureSkyPartition::draw(StelPainter& sPainter, const Vec3d &obsVel
209217

210218
if (linkStars.length()>1)
211219
{
212-
// Chinese systems: Unequal partitions defined by stars.
220+
// Chinese systems: Unequal partitions defined by stars. We can also safely assume extent has only one value.
213221
foreach(const int starId, linkStars)
214222
{
215223
//qDebug() << "drawing line for HIP" << starId;
@@ -220,8 +228,8 @@ void StelSkyCultureSkyPartition::draw(StelPainter& sPainter, const Vec3d &obsVel
220228
StelUtils::rectToSphe(&ra, &dec, posDate);
221229
Vec3d eqPt, nPt, sPt;
222230
StelUtils::spheToRect(ra, 0., eqPt);
223-
StelUtils::spheToRect(ra, extent*M_PI_180, nPt);
224-
StelUtils::spheToRect(ra, -extent*M_PI_180, sPt);
231+
StelUtils::spheToRect(ra, extent.at(0)*M_PI_180, nPt);
232+
StelUtils::spheToRect(ra, -extent.at(0)*M_PI_180, sPt);
225233
sPainter.drawGreatCircleArc(eqPt, nPt);
226234
sPainter.drawGreatCircleArc(eqPt, sPt);
227235
//qDebug() << "done line for HIP" << starId;
@@ -239,20 +247,45 @@ void StelSkyCultureSkyPartition::draw(StelPainter& sPainter, const Vec3d &obsVel
239247
const double lng=(360./partitions[0]*p +offsetFromAries)*M_PI_180;
240248
Vec3d eqPt, nPt, sPt;
241249
StelUtils::spheToRect(lng, 0., eqPt);
242-
StelUtils::spheToRect(lng, extent*M_PI_180, nPt);
243-
StelUtils::spheToRect(lng, -extent*M_PI_180, sPt);
250+
double nExt, sExt;
251+
if (extent.length()==1)
252+
{
253+
nExt=extent.at(0);
254+
sExt=-extent.at(0);
255+
}
256+
else
257+
{
258+
Q_ASSERT(extent.length() == 2*partitions.length());
259+
nExt=qMax(extent.at(2*p), extent.at(2*((p-1+partitions[0]) % partitions[0])));
260+
sExt=qMin(extent.at(2*p+1), extent.at(2*((p-1+partitions[0]) % partitions[0])+1));
261+
}
262+
StelUtils::spheToRect(lng, nExt*M_PI_180, nPt);
263+
StelUtils::spheToRect(lng, sExt*M_PI_180, sPt);
244264
sPainter.drawGreatCircleArc(eqPt, nPt);
245265
sPainter.drawGreatCircleArc(eqPt, sPt);
246266
}
247267
}
248268

249269
// Draw top/bottom lines where applicable
250-
if (extent<90.)
270+
if ((extent.length()==1) && (extent.at(0)<90.))
251271
{
252272
// Get the bounding halfspace
253273
const SphericalCap& viewPortSphericalCap = sPainter.getProjector()->getBoundingCap();
254-
drawCap(sPainter, viewPortSphericalCap, extent);
255-
drawCap(sPainter, viewPortSphericalCap, -extent);
274+
drawCap(sPainter, viewPortSphericalCap, extent.at(0));
275+
drawCap(sPainter, viewPortSphericalCap, -extent.at(0));
276+
}
277+
else if (extent.length()>1)
278+
{
279+
// TODO: Arab LM may show sectioned boxes.
280+
for (int p=0; p<partitions[0]; ++p)
281+
{
282+
// Get the bounding halfspace
283+
const SphericalCap& viewPortSphericalCap = sPainter.getProjector()->getBoundingCap();
284+
// TODO: draw 2 small arcs per LM in the given extent latitudes
285+
drawMansionCap(sPainter, viewPortSphericalCap, extent.at(2*p), p*360.0/partitions[0]+offsetFromAries, (p+1)*360.0/partitions[0]+offsetFromAries);
286+
drawMansionCap(sPainter, viewPortSphericalCap, extent.at(2*p+1), p*360.0/partitions[0]+offsetFromAries, (p+1)*360.0/partitions[0]+offsetFromAries);
287+
}
288+
256289
}
257290

258291
centerLine->setCulturalOffset(offsetFromAries);
@@ -266,7 +299,8 @@ void StelSkyCultureSkyPartition::draw(StelPainter& sPainter, const Vec3d &obsVel
266299
// To have tilted labels, we project a point 0.1deg from the actual label point and derive screen-based angle.
267300
double lng = (360./partitions[0]*i + 2.+offsetFromAries)*M_PI_180;
268301
double lng1 = (360./partitions[0]*i + 2.+offsetFromAries + txtOffset)*M_PI_180;
269-
double lat = (extent<50. ? -extent+0.2 : -10.) *M_PI_180;
302+
// the displayed latitude is defined in the first LM.
303+
double lat = (extent.at(0)<50. ? -extent.at(0)+0.2 : -10.) *M_PI_180;
270304
Vec3d pos, pos1, scr, scr1;
271305
StelUtils::spheToRect(lng, lat, pos);
272306
StelUtils::spheToRect(lng1, lat, pos1);
@@ -290,7 +324,7 @@ void StelSkyCultureSkyPartition::draw(StelPainter& sPainter, const Vec3d &obsVel
290324

291325
ra += 2.*M_PI_180; // push a bit into the mansion area. Problem: the narrow mansions...
292326
double ra1 = ra+txtOffset*M_PI_180;
293-
double dec1 = (extent<50. ? -extent+0.2 : -10.) *M_PI_180;
327+
double dec1 = (extent.at(0)<50. ? -extent.at(0)+0.2 : -10.) *M_PI_180;
294328
Vec3d pos, pos1, scr, scr1;
295329
StelUtils::spheToRect(ra, dec1, pos);
296330
StelUtils::spheToRect(ra1, dec1, pos1);
@@ -313,7 +347,7 @@ void StelSkyCultureSkyPartition::draw(StelPainter& sPainter, const Vec3d &obsVel
313347
// To have tilted labels, we project a point 0.1deg from the actual label point and derive screen-based angle.
314348
double lng = (360./partitions[0]*(double(i)+0.5) + 2.+offsetFromAries)*M_PI_180;
315349
double lng1 = (360./partitions[0]*(double(i)+0.5) + 2.+offsetFromAries+txtOffset)*M_PI_180;
316-
double lat = (extent<50. ? -extent+0.2 : -10.) *M_PI_180;
350+
double lat = (extent.at(0)<50. ? -extent.at(0)+0.2 : -10.) *M_PI_180;
317351
Vec3d pos, pos1, scr, scr1;
318352
StelUtils::spheToRect(lng, lat, pos);
319353
StelUtils::spheToRect(lng1, lat, pos1);
@@ -339,7 +373,7 @@ void StelSkyCultureSkyPartition::draw(StelPainter& sPainter, const Vec3d &obsVel
339373
StelUtils::rectToSphe(&ra, &dec, mid);
340374

341375
double ra1 = ra+txtOffset*M_PI_180;
342-
double dec1 = (extent<50. ? -extent+0.2 : -10.) *M_PI_180;
376+
double dec1 = (extent.at(0)<50. ? -extent.at(0)+0.2 : -10.) *M_PI_180;
343377
Vec3d pos, pos1, scr, scr1;
344378
StelUtils::spheToRect(ra, dec1, pos);
345379
StelUtils::spheToRect(ra1, dec1, pos1);
@@ -357,7 +391,7 @@ void StelSkyCultureSkyPartition::draw(StelPainter& sPainter, const Vec3d &obsVel
357391
// shamelessly copied from SkyLine::draw (small circles part)
358392
void StelSkyCultureSkyPartition::drawCap(StelPainter &sPainter, const SphericalCap& viewPortSphericalCap, double latDeg) const
359393
{
360-
double lat=latDeg*M_PI_180;
394+
const double lat=latDeg*M_PI_180;
361395
SphericalCap declinationCap(Vec3d(0.,0.,1.), std::sin(lat));
362396
const Vec3d rotCenter(0,0,declinationCap.d);
363397

@@ -400,6 +434,18 @@ void StelSkyCultureSkyPartition::drawCap(StelPainter &sPainter, const SphericalC
400434
}
401435
}
402436

437+
void StelSkyCultureSkyPartition::drawMansionCap(StelPainter &sPainter, const SphericalCap& viewPortSphericalCap, double latDeg, double lon1, double lon2) const
438+
{
439+
const double lat=latDeg*M_PI_180;
440+
SphericalCap declinationCap(Vec3d(0.,0.,1.), std::sin(lat));
441+
const Vec3d rotCenter(0,0,declinationCap.d);
442+
Vec3d pt1, pt2;
443+
StelUtils::spheToRect(lon1*M_PI_180, lat, pt1); //pt1.normalize();
444+
StelUtils::spheToRect(lon2*M_PI_180, lat, pt2); //pt2.normalize();
445+
sPainter.drawSmallCircleArc(pt1, pt2, rotCenter, nullptr, nullptr);
446+
}
447+
448+
403449
void StelSkyCultureSkyPartition::setFontSize(int newFontSize)
404450
{
405451
font.setPixelSize(newFontSize);

src/core/StelSkyCultureSkyPartition.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,18 @@ friend ConstellationMgr;
155155

156156
private:
157157
void drawCap(StelPainter &sPainter, const SphericalCap& viewPortSphericalCap, double latDeg) const;
158+
void drawMansionCap(StelPainter &sPainter, const SphericalCap& viewPortSphericalCap, double latDeg, double lon1, double lon2) const;
158159
//void drawLabels(StelPainter &sPainter) const;
159160
//! Update i18n names from English names according to current locale.
160161
void updateI18n();
161162

162163
StelCore::FrameType frameType; //!< Useful seem only: FrameObservercentricEclipticOfDate (e.g. Zodiac), FrameEquinoxEqu (e.g. Chin. Lunar Mansions)
163-
QVector<double> partitions; //!< A partition into [0] large parts of [1] smaller parts of [2] smaller parts... Currently only 2-part zodiacs [12, 30] or nakshatras [27, 4] are in use.
164+
QList<int> partitions; //!< A partition into [0] large parts of [1] smaller parts of [2] smaller parts... Currently only 2-part zodiacs [12, 30] or nakshatras [27, 4] are in use.
164165
StelObject::CulturalName name; //!< Full culture-sensitive naming support: name of the system.
165166
QList<StelObject::CulturalName> names; //!< Full culture-sensitive naming support: names of the first-grade partition.
166167
QStringList symbols; //!< A list of very short or optimally 1-char Unicode strings with representative symbols usable as abbreviations.
167-
double extent; //!< (degrees) the displayed partition zone runs so far north and south of the center line.
168+
QList<double> extent; //!< (degrees) If only one element (usual case), the displayed partition zone runs so far north and south of the center line.
169+
//!< Else, the list MUST contain 2x number of partitions[0], and contains north and south latitudes of each lunar station.
168170
public:
169171
SkyLine *centerLine; //!< See GridlineMgr: a CUSTOM_ECLIPTIC or CUSTOM_EQUATORIAL SkyLine
170172
private:

0 commit comments

Comments
 (0)