So, ich bin gerade dran den Flottenscanner in meinem 2D-Universum einzubauen , folgende Spezifikation, damit ihr wisst von was ich rede
- Universum ist 2000x2000 Lichtjahre Koordinatensystem
- Scannerreichweite 200 Lichtjahre
- Auf beliebigen Planeten können Scanner errichtet werden (also auch überlappende Zonen)
- Flotten sind sowieso irgendwo
Mein Lösungsansatz ist nun folgender:
1) Ich gehe alle Planeten mit Scanner der Reihe nach durch
1a) Ich wähle grob ein Quadrat ausgehend von Planetenkoordinate +- 200 in x und y Richtung
1b) Alle Flotten deren Koordinaten innerhalb dieses Quadrats liegen, werden genauer untersucht (Auf Abstand zum Kreismittelpunkt)
1a und 1b werden solange wiederholt bis alle Planeten durchgegangen wurden. Flotten die bereits durch 1b bereits einmal als im Bereich eines Scanner liegends klassifiziert wurden, werden in folgenden Durchgängen ignoriert.
Ich möchte ja das das ganze so schnell wie möglich abläuft, es kann davon ausgegangen werden, das alle benötigten Daten in statischen Klassen vorhanden sind und keine Datenbankzugriffe mehr notwendig sind.
Ist jeder mit meiner Vorgehensweise einverstanden, oder gibt es vielleicht noch Verbesserungsvorschläge?
Flottenscanner in 2D
gepostet vor 17 Jahre, 9 Monate von RaydenDD
gepostet vor 17 Jahre, 9 Monate von Drezil
wenn die scannerreichweite statisch ist, dann wird dein system so zielmlich das effizienteste sein ... sofern man das so beurteilen kann.
ich für meinen teil lasse mir von der db schon zurückgeben, was sichbar ist und was nicht. (was nicht sichtbar ist, ist nicht im resultset). da hab ich auch kein problem mit sich bewegenden scanerquellen.
wenn deine scannerquellen statisch sind, dann kann man noch weiter optimieren.
z.b. kann man das universum intern in 100x100-blöcke rastern und dann in einer bitmap die informationen ablegen (0: nicht bekannt; 1: teilweise bekannt; 2: vollständig bekannt) und könnte so schon größere bereiche ausschliessen/ ohne prüfung durchwinken.
allerdings fände ich es (ich weiss nicht genau, wie du arbeitest, daher nur ein schuss ins blaue) ressourcentechnisch ungeschickt für nur 1-2 berechnungen alle flotten, planeten, weissdergeier aus der db zu pullen und in objekte zu klatschen .. ich stell mir gerade den ram-verbrauch bei 10000 fliegenden flotten vor ..
bei mir fange ich z.b. alle sonnen im sichtradius so ab (planeten, flotten, etc ähnlich):
select /* alle sonnendaten */
so.sid,
so.styp,
so.x,
so.y,
so.name
from
sonnen so, /* alle sonnen */
gebaeude g /* alle scanner + planiposition auf der sie stehen + sonnenposition zur errechnung der planiposition */
join planeten p on (g.pid=p.pid)
join sonnen s on (s.sid=p.sid)
where
/* pow(x,2) + pow(y,2) < pow(radius,2) */
pow(
so.x-s.x-(p.pnr*cos(unix_timestamp()*p.bahnfaktor/(p.pnr*13750.987083139757010431557155385)))
,2)
/*x-differenz sonne <-> aktuelle plani-pos*/
+pow(
so.y-s.y-(p.pnr*sin(unix_timestamp()*p.bahnfaktor/(p.pnr*13750.987083139757010431557155385)))
,2)
/*y-differenz sonne <-> aktuelle plani-pos*/
< case g.gid
when 50 then pow(500 - 500*pow(0.75,g.stufe),2) /* scan-geb 1 */
when 51 then pow(1000 - 1000*pow(0.8,g.stufe),2) /* scan-geb 2 */
when 52 then pow(750 - 750*pow(0.90,g.stufe),2) /* scan-geb 3 */
when 53 then pow(1250 - 1250*pow(0.95,g.stufe),2) end /* scan-geb 4 */
AND p.uid='.$uid.'
AND g.gid in (50,51,52,53)
group by so.sid,so.styp,so.x,so.y,so.name
order by so.sid asc
hab nen paar kommentare reingemacht .. sollte so verständlich sein.
so bekomme ich einfach nur eine liste und erspare mir weiter prüfungen
(ja, schlagt mich, weil ich keine views verwende ...)
ich für meinen teil lasse mir von der db schon zurückgeben, was sichbar ist und was nicht. (was nicht sichtbar ist, ist nicht im resultset). da hab ich auch kein problem mit sich bewegenden scanerquellen.
wenn deine scannerquellen statisch sind, dann kann man noch weiter optimieren.
z.b. kann man das universum intern in 100x100-blöcke rastern und dann in einer bitmap die informationen ablegen (0: nicht bekannt; 1: teilweise bekannt; 2: vollständig bekannt) und könnte so schon größere bereiche ausschliessen/ ohne prüfung durchwinken.
allerdings fände ich es (ich weiss nicht genau, wie du arbeitest, daher nur ein schuss ins blaue) ressourcentechnisch ungeschickt für nur 1-2 berechnungen alle flotten, planeten, weissdergeier aus der db zu pullen und in objekte zu klatschen .. ich stell mir gerade den ram-verbrauch bei 10000 fliegenden flotten vor ..
bei mir fange ich z.b. alle sonnen im sichtradius so ab (planeten, flotten, etc ähnlich):
select /* alle sonnendaten */
so.sid,
so.styp,
so.x,
so.y,
so.name
from
sonnen so, /* alle sonnen */
gebaeude g /* alle scanner + planiposition auf der sie stehen + sonnenposition zur errechnung der planiposition */
join planeten p on (g.pid=p.pid)
join sonnen s on (s.sid=p.sid)
where
/* pow(x,2) + pow(y,2) < pow(radius,2) */
pow(
so.x-s.x-(p.pnr*cos(unix_timestamp()*p.bahnfaktor/(p.pnr*13750.987083139757010431557155385)))
,2)
/*x-differenz sonne <-> aktuelle plani-pos*/
+pow(
so.y-s.y-(p.pnr*sin(unix_timestamp()*p.bahnfaktor/(p.pnr*13750.987083139757010431557155385)))
,2)
/*y-differenz sonne <-> aktuelle plani-pos*/
< case g.gid
when 50 then pow(500 - 500*pow(0.75,g.stufe),2) /* scan-geb 1 */
when 51 then pow(1000 - 1000*pow(0.8,g.stufe),2) /* scan-geb 2 */
when 52 then pow(750 - 750*pow(0.90,g.stufe),2) /* scan-geb 3 */
when 53 then pow(1250 - 1250*pow(0.95,g.stufe),2) end /* scan-geb 4 */
AND p.uid='.$uid.'
AND g.gid in (50,51,52,53)
group by so.sid,so.styp,so.x,so.y,so.name
order by so.sid asc
hab nen paar kommentare reingemacht .. sollte so verständlich sein.
so bekomme ich einfach nur eine liste und erspare mir weiter prüfungen
(ja, schlagt mich, weil ich keine views verwende ...)