# umgebungsmodell
# bezug dazu 
# noch nicht richtig erster versuch

import rhinoscriptsyntax as rs
import random

layer_name = "DGM_5m"

objs = rs.ObjectsByLayer(layer_name) or []

peak = None
for oid in objs:
    bb = rs.BoundingBox(oid)
    if not bb:
        continue
    p = max(bb, key=lambda pt: pt[2])
    if (peak is None) or (p[2] > peak[2]):
        peak = p

if peak is None:
    print("nicht")
else:
    rs.AddPoint(peak)
    print("peak gefunden:", peak)



##### PROJEKT AMELIA EARHART
##### VERENA ULM GRUBEREINS

### ersten schritte fuer das projekt keine surfaces 
##### schritt eins wolkenbett


#hilfe
# zufaelliger punkt auf einer kugeloberflaeche


def zufalls_kugelpunkt(zentrum, radius):
    v = rs.VectorCreate(
        [random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1)],
        [0, 0, 0])
    if rs.VectorLength(v) == 0:
        v = [1, 0, 0] # falls vektor null sicherheitsmassnahme
    # normieren auf einheitsvektor befehl
    v = rs.VectorUnitize(v)
    # verdrehen in allen raumachsen
    v = rs.VectorRotate(v, random.uniform(0, 360), [1, 0, 0])
    v = rs.VectorRotate(v, random.uniform(0, 360), [0, 1, 0])
    v = rs.VectorRotate(v, random.uniform(0, 360), [0, 0, 1])
    
    # skalieren auf kugelradius
    v = rs.VectorScale(v, radius)
    
    # punkt = zentrum plus vektor
    return [zentrum[0] + v[0], zentrum[1] + v[1], zentrum[2] + v[2]]

# punktwolke auf einer kugel
def kugel_punktwolke(zentrum, radius=10, dichte=150):
    pts = []
    for i in range(dichte):
        pts.append(zufalls_kugelpunkt(zentrum, radius))
    return pts

# eine wolkeneinheit besteht aus mehreren ueberlagerte kugeln
def wolkeneinheit_erzeugen(zentrum, radius_basis, gruppenname):
    if not rs.IsGroup(gruppenname):
        rs.AddGroup(gruppenname) # gruppe anlegen
    # Anzahl Kugeln pro Wolkeneinheit
    kugeln = random.randint(2, 5)
    vorheriges_zentrum = None
    
    for i in range(kugeln):
        # radius variieren nur leicht 
        radius = radius_basis * random.uniform(0.7, 1.25)
        
        
        # erste Kugel zentriert
        if i == 0:
            c = [zentrum[0], zentrum[1], zentrum[2]]
        else:
            offset = [
                random.uniform(-radius * 0.55, radius * 0.55),
                random.uniform(-radius * 0.55, radius * 0.55),
                random.uniform(-radius * 0.07, radius * 0.07)] ### alle anderen kugeln sind leicht versetzt fuer mehr lebendigkeit
            c = [
                vorheriges_zentrum[0] + offset[0],
                vorheriges_zentrum[1] + offset[1],
                vorheriges_zentrum[2] + offset[2]]
        pts = kugel_punktwolke(c, radius, dichte=punkte_pro_kugel)
        pts_id = rs.AddPoints(pts)
        
        # farbgebungenn fuer die wolkenpunkte
        farbe = [
            random.randint(180, 200), 
            random.randint(210, 230),  
            random.randint(240, 255)] 
        rs.ObjectColor(pts_id, farbe)
        rs.AddObjectToGroup(pts_id, gruppenname)
        vorheriges_zentrum = c


### wichtige parameter
hoehen_offset = 25               # wolkenhoehe
hoehe = peak[2] + hoehen_offset
radius_basis_zentrum = 14  # grosse wolken
radius_basis = 10          # kleinere wolken
punkte_pro_kugel = 150     # punktdichte pro kugel

lenXmax = 60   # laenge
lenYmax = 90   # breite
lenZmax = 18   # hoehe
minFac = 0.7   # variation der volumina
anz_wolken_pro_cluster = 12  # wolkeneinheiten pro cluster

# drei cluster drei zentren
cluster_zentren = [
    [peak[0] - 30, peak[1] - 20, hoehe],
    [peak[0], peak[1], hoehe], [peak[0] + 30, peak[1] + 20, hoehe],]



def cluster_erzeugen(zentrum):
    wolkeneinheit_erzeugen(zentrum, radius_basis_zentrum, "WolkenZentrum")
    # mehrere wolkeneinheiten in einem volumen um das zentrum
    for i in range(anz_wolken_pro_cluster):
        lenX = random.uniform(lenXmax * minFac, lenXmax)
        lenY = random.uniform(lenYmax * minFac, lenYmax)
        lenZ = random.uniform(lenZmax * minFac, lenZmax)
        off = [
            random.uniform(-lenX * 0.5, lenX * 0.5),
            random.uniform(-lenY * 0.5, lenY * 0.5),
            random.uniform(-lenZ * 0.5, lenZ * 0.5)]
        c = [zentrum[0] + off[0],
             zentrum[1] + off[1],
             zentrum[2] + off[2]]
        wolkeneinheit_erzeugen(c, radius_basis, "Wolken")

# zentren erzeugen cluster
for cen in cluster_zentren:
    cluster_erzeugen(cen)

### fuellwolken sind zwischen den zentren fuer ein schoenes wolkenbett
min_x = min(c[0] for c in cluster_zentren) - 20
max_x = max(c[0] for c in cluster_zentren) + 20
min_y = min(c[1] for c in cluster_zentren) - 35
max_y = max(c[1] for c in cluster_zentren) + 35

for i in range(18):
    c = [
        random.uniform(min_x, max_x),
        random.uniform(min_y, max_y),
        hoehe + random.uniform(-4, 4)]
    wolkeneinheit_erzeugen(c, radius_basis * 0.9, "WolkenFuellung")

rs.EnableRedraw(True)
rs.ZoomExtents()


### schritt zwei 
### die plattform LANDEPLATTFORM 

# layer
rs.AddLayer("LandeplattformAussen", color=(80,80,80))
rs.CurrentLayer("LandeplattformAussen")

# parameter fuer die plattform
plattform_breite = 35 # breite in x richtung
plattform_tiefe = 30   # breite in yrichtung
linien_abstand = 0.3
plattform_hoehe = 55  # hoehe ueber dem boden
# verlaengerung in xrichtung  nachtraegliche ausbesserung 
# plattform wird auf beiden seiten verlaengert fuer fluglandeplatz
verlaengerung_x = 33       
gesamt_breite_x = plattform_breite + 2 * verlaengerung_x

# definieren der rechteckpunkte zentriert
# vier eckpunkte
# rechteck ist 101meter in x und 30m in y
pA = [-gesamt_breite_x/2, -plattform_tiefe/2, plattform_hoehe]
pB = [ gesamt_breite_x/2, -plattform_tiefe/2, plattform_hoehe]
pC = [ gesamt_breite_x/2,  plattform_tiefe/2,  plattform_hoehe]
pD = [-gesamt_breite_x/2,  plattform_tiefe/2,  plattform_hoehe]

# zeichnen des rechtecks als polyline
rs.AddPolyline([pA, pB, pC, pD, pA])

# verdichtung eins
# raster 
#anzahl der linien horizontal in die yrichtung
anzahl = int(plattform_tiefe / linien_abstand) + 1

# farbverlauf 
# abhaengig vom abstand zur mitte wird die linie heller oder dunkler
for i in range(anzahl):
    # YPosition der Linie 
    y = pA[1] + i * linien_abstand
    line_id = rs.AddLine([pA[0], y, plattform_hoehe], [pB[0], y, plattform_hoehe])
    # abstand von der mitte in Yrichtung null mitte eins rand
    dist = abs(y) / (plattform_tiefe / 2.0)
    if dist > 1.0:
        dist = 1.0
    # grau verlauf 
    grau = int(80 + dist * (200 - 80))  # mitte 80 dunkel rand 200 hell
    rs.ObjectColor(line_id, (grau, grau, grau))
    
# verdichtung zwei 
# kreuzlinien in x richtung
anzahl2 = int(gesamt_breite_x / linien_abstand) + 1

# farbverlauf
for j in range(anzahl2):
    x = pA[0] + j * linien_abstand
    line_id = rs.AddLine([x, pA[1], plattform_hoehe], [x, pD[1], plattform_hoehe])
    # abstand von der mitte in x richtung null mitte eins rand
    dist = abs(x) / (gesamt_breite_x / 2.0)
    if dist > 1.0:
        dist = 1.0
    # grauverlauf innen dunkler aussen heller
    grau = int(80 + dist * (200 - 80))
    rs.ObjectColor(line_id, (grau, grau, grau))


### ende landeplattform







### schritt drei
### kennzeichnung landeplatz 


# layer fuer das kreuz erstellen



rs.AddLayer("KreuzBlau", color=(100,180,255))
rs.CurrentLayer("KreuzBlau")

skalierung = 1.5   # im nachhinein kreuz verkleinert 


kreuz_breite = (plattform_breite * 0.35) / skalierung
kreuz_laenge = (plattform_tiefe * 0.7)   / skalierung
kreuz_dicke = 0.5
kreuz_hoehe = plattform_hoehe + kreuz_dicke

linien_abstand_kreuz = 0.1


# horizontales Rechteck 
hA = [-kreuz_laenge/2, -kreuz_breite/6, kreuz_hoehe]
hB = [ kreuz_laenge/2, -kreuz_breite/6, kreuz_hoehe]
hC = [ kreuz_laenge/2,  kreuz_breite/6, kreuz_hoehe]
hD = [-kreuz_laenge/2,  kreuz_breite/6, kreuz_hoehe]
rs.AddPolyline([hA, hB, hC, hD, hA])


# vertikales Rechteck
vA = [-kreuz_breite/6, -kreuz_laenge/2, kreuz_hoehe]
vB = [ kreuz_breite/6, -kreuz_laenge/2, kreuz_hoehe]
vC = [ kreuz_breite/6,  kreuz_laenge/2, kreuz_hoehe]
vD = [-kreuz_breite/6,  kreuz_laenge/2, kreuz_hoehe]
rs.AddPolyline([vA, vB, vC, vD, vA])

### fuer die verdichtung
hoehe_min = -kreuz_breite/6
hoehe_max =  kreuz_breite/6
anzahl_h = int((hoehe_max - hoehe_min) / linien_abstand_kreuz) + 1

for i in range(anzahl_h):
    y = hoehe_min + i * linien_abstand_kreuz
    rs.AddLine([-kreuz_laenge/2, y, kreuz_hoehe], [kreuz_laenge/2, y, kreuz_hoehe])

### fuer die verdichtung
breite_min = -kreuz_breite/6
breite_max =  kreuz_breite/6
anzahl_v = int((breite_max - breite_min) / linien_abstand_kreuz) + 1

for j in range(anzahl_v):
    x = breite_min + j * linien_abstand_kreuz
    rs.AddLine([x, -kreuz_laenge/2, kreuz_hoehe], [x, kreuz_laenge/2, kreuz_hoehe])


#### weisser rahmen um das kreuz

rs.AddLayer("KreuzRahmenWeiss", color=(255,255,255))
rs.CurrentLayer("KreuzRahmenWeiss")

rahmen_offset = 0.0   # Dicke des weissen Rahmens

# horizontaler Rahmen
rs.AddPolyline([
    [-kreuz_laenge/2 - rahmen_offset, -kreuz_breite/6 - rahmen_offset, kreuz_hoehe],
    [ kreuz_laenge/2 + rahmen_offset, -kreuz_breite/6 - rahmen_offset, kreuz_hoehe],
    [ kreuz_laenge/2 + rahmen_offset,  kreuz_breite/6 + rahmen_offset, kreuz_hoehe],
    [-kreuz_laenge/2 - rahmen_offset,  kreuz_breite/6 + rahmen_offset, kreuz_hoehe],
    [-kreuz_laenge/2 - rahmen_offset, -kreuz_breite/6 - rahmen_offset, kreuz_hoehe]
])

# vertikaler Rahmen
rs.AddPolyline([
    [-kreuz_breite/6 - rahmen_offset, -kreuz_laenge/2 - rahmen_offset, kreuz_hoehe],
    [ kreuz_breite/6 + rahmen_offset, -kreuz_laenge/2 - rahmen_offset, kreuz_hoehe],
    [ kreuz_breite/6 + rahmen_offset,  kreuz_laenge/2 + rahmen_offset, kreuz_hoehe],
    [-kreuz_breite/6 - rahmen_offset,  kreuz_laenge/2 + rahmen_offset, kreuz_hoehe],
    [-kreuz_breite/6 - rahmen_offset, -kreuz_laenge/2 - rahmen_offset, kreuz_hoehe]
])


rs.AddLine(B, C)
rs.AddLine(A, D)



#### ende bis jetzt
## naechster schritt
## flugzeughangar klein fuer amelia earhart



