Darstellung von einem Messgitter

Neue Frage »

Toxman Auf diesen Beitrag antworten »
Darstellung von einem Messgitter
Hi
Als Info-Projekt sollen wir ein Messgitter von Höhenlinien grafisch darstellen, dh. ich soll die Fläche zwischen 4 Messpunkten so mit Farbe ausfüllen, dass ich an der Farbe eines Pixels erkennen kann, wie hoch es etwa ist. (bei dem angehängten Bild hat der linke untere Punkt die höhe 250 und die restlichen Höhe=0)
Ich hab schon was implementiert (siehe zweites Bild) nur hab ich da diese Linie, die nicht so gut aussieht.
Die Idee dahinter war eine Art Ebenendarstellung per Vektoraddition.

Hat jemand schon mal so was gemacht oder eine Idee wie man so was machen kann? Hilfe Hilfe Hilfe
Toxman Auf diesen Beitrag antworten »

hier das zweite Bild
kurellajunior Auf diesen Beitrag antworten »

Ja, so etwas habe ich schon gemacht. Jedoch fehlt bei Dir die Angabe wie die Höhen abfallen (Funktion wäre cool). Wenn wir von x- und y- Ausdehnung reden, ist es am einfachsten, wenn Du für jede der beiden eine gleichmäßige Vorschrift hättest (im einfachsten Fall linear). Auch sollte der Farbübergang (RGB, Farbkreis, etc. klar sein)

Ich versuch mal aus dem Stand Pseudojava der Einfachheit halber in Graustufen:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
Bild[][] g = new Bild[n][n]; // n Anzahl der Pixel
Bild[0][0].farbe = 0;
Bild[0][n-1].farbe = 255;
Bild[n-1][0].farbe = 255;
Bild[n-1][n-1].farbe = 255;

function calculateColors(Bild[][]) {
  for (int i=1; i<n-1; i++) {
      // hier sitzt der Hase im Pfeffer! Berechnung der beiden Grenzreihen
    Bild[0][i].farbe = (Bild[0][n-1] - Bild[0][0].farbe)/n*i;
    Bild[n-1][i].farbe = (Bild[n-1][n-1] - Bild[n-1][0].farbe)/n*i;

    for (int j=1; j<n; j++) {
        // Berechnung der Reihen zwischen den Grenzen
      Bild[j][i].farbe = (Bild[0][i].farbe - Bild[n-1][i].farbe)/n*j;
    }
  }
}

Ansatz klar?
(Bild[0][n-1] - Bild[0][0].farbe)/n*i sollte natürlich in einer eigenen Funktion stehen, die diese vier Parameter bekommt und dem jeweiligen Farbmodell angepasst ist. Idealerweise ist das ein Funktion von Bild selbst...

Wo die Linie herkommt ist mir ohne Kenntnis des Algorithmusses nicht klar verwirrt .
EDIT: Doch, die Linie kommt zustande, weil du den Abfall nicht über die ganze Breite/Höhe hast, sondern erst von der Diagonale aus. Das hängt wie gesagt von der Funktion ab, mit der du die Steigung beschreibst.
Wenn noch Fragen sind einfach los.
Toxman Auf diesen Beitrag antworten »

Meine Funktion sieht so aus: [Delphi Language (Pascal)]
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
procedure TForm1.Square(a,b,c,d: integer); 
var 
x,y: integer; 
ab, ac, db, dc : real; // Steigung der Querstrecken 
hab,hac,hdb, hcd ,h: real; 
// L: Länge/Breite des Quadrats
begin 
// Links unten 
ab:= (b-a)/L;  // Steigung der Seitenlinien 
ac:= (c-a)/L; 

// rechts oben 
db:= (b-d)/L; 
dc:= (c-d)/L; 


for x:=0 to L do 
        for y:=0 to L do 
        begin 
        if x<y then  // links untern 
                begin 
                hac:= (L-y)*ac;   // Steigung in c-Richtung 
                hab:= (  x)*ab;   // in B-Richtung 
                h  := a+hac+hab;  // aufsummiert und fertig ??? 
                end 
        else         // rechts oben 
                begin 
                hcd:= (L-x)*dc; 
                hdb:= (  y)*db; 
                h  := d+hcd+hdb; 
                end; 

        Img.Canvas.Pixels[x,y]:=color(round(h)); 
        end; 
end; 

Ich gehe von einer lineraren Funktion aus. Die Unterscheidung in links unter und rechts oben nutze ich weil ich das Quadrat in zwei Dreiecke zerlege um dann eine Ebenengleichung aufstellen kann.
Danke für deinen Code. :] Ich hab leider keine Kenntnisse in Java und hab ein paar Probleme bei
code:
1:
2:
Bild[0][i].farbe = (Bild[0][n-1] - Bild[0][0].farbe)/n*i;
Bild[n-1][i].farbe = (Bild[n-1][n-1] - Bild[n-1][0].farbe)/n*i;

Hast du mit diesem Algorhytmus schon mal ein Bild mit den von mit benutzten Eckhöhen gezeichnet?

THXbyTOX
kurellajunior Auf diesen Beitrag antworten »

Hi,

mir fallen zwei logische Fehler auf:
  1. Ein beliebiges REchteck (ABCD) wird in der Regel gegen den Uhrzeigersinn beschriftet. Also linksunten: A, rechtsunten B, rechtsoben C und linksoben D.
    Die Seitenkanten sind daher AB, BC, CD und DA. Die Diagonalen sind also AC und BD!
  2. Wenn Du sowohl in x-Richtung als auch in y-Richtung einen linearen Abfall annimmst, ist die resultierende Fläche keine Ebene!!! Um Dir die resultierende Fläche vorzustellen, nimm ein quadratisches Stück Stoff und versuche es zwischen den 4 Punkten zu spannen. Ich hab den Fachbegriff für diese Flächenform vergessen. (Parabolloid?)


Durch die Aufteilung in zwei Dreiecke entsteht die von Dir beobachtete Linie, da Du zwei Dreiecke aneinander "pappst".
Zitat:
Original von Toxman
code:
1:
2:
3:
4:
5:
procedure TForm1.Square(a,b,c,d: integer); 
        Img.Canvas.Pixels[x,y]:=color(round(h)); 
        end; 
end;

Ich hab leider keine Kenntnisse in Java und hab ein paar Probleme bei
code:
1:
2:
3:
Bild[0][i].farbe = (Bild[0][n-1] - Bild[0][0].farbe)/n*i;
Bild[n-1][i].farbe = (Bild[n-1][n-1] - Bild[n-1][0].farbe)/n*i;


Der Plan ist, dass Du zu erst Zwei Seitenkanten berechnest, also zum Beispiel alle Punkte von AB und CD. Bei Deinem Beispiel also A=250. Heißt bei linearem Abfall von A nach B die dazwischen liegenden Punkte berechnen. Da ist Deine Methode über den Anstieg völlig korrekt.
Bei CD sind alle Punkte=0, trotzdem per Formel, falls mal andere Höhen kommen. Augenzwinkern
Jetzt nimmst du alle Pixellinien zwischen AB und CD, rechnest jeweils den Anstieg zwischen der Höhe des unteren Punktes und der des oberen Punktes und berechnest die Zwischenpunkte wie zuvor.
Das riecht nach einer Funktion.
Meine TP-Zeit ist lange her, ich versuchs mal in etwa zu erläutern
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure fillPoints(bild:Img, x1,y1,x2,y2: integer) // Das Bild und die Koordinaten von Start- und Endpunkt.
   steig : real;
   pixel : integer
begin
   if x1<>x2 then //Der Abstand zwischen den beiden Punkten, nur für Geraden!
      pixel := x1-x2; 
   else
      pixel := y1-y2;
   end;
   steig := (bild.Canvas.Pixels[x1,y1] - bild.Canvas.Pixels[x2,y2]) / pixel;
   // Jetzt die For-Schleife entweder für x oder y wie gehabt - und fertig.
end;

Zitat:
Hast du mit diesem Algorhytmus schon mal ein Bild mit den von mit benutzten Eckhöhen gezeichnet?

Leider nein. Wenn ich die Funktionsvorschrift finde, deren partieller Anstieg in x- und y- Richtung inear ist, kannst Du die ja mal in einen 3D-Funktionsplotter eingeben, kann ich aber nicht versprechen unglücklich .
Toxman Auf diesen Beitrag antworten »

zu den Fehlern:
1) Ich hatte erst ein Dreieck, dass ich math. korrekt benannt hatte und hab dann noch eine Ecke hinzugefügt. Danach wollte ich nicht alles umschreiben und hab so eine etwas komische Benennung erzielt.
2) Wie du schon selbst gesehen hast (Durch die Aufteilung in zwei Dreiecke entsteht die von Dir beobachtete Linie, da Du zwei Dreiecke aneinander "pappst". ) baue ich das Quadrat aus 2 Dreiecken, denen ich jeweils eine Ebenengleichung zudenke. Dadurch kann ich so ein 'Quadrat mit Falte' darstellen.

Danke schon mal. Ich war vorhin skaten und hatte da eine neue Idee zur Einteilung des Quadrats, die ich erstmal versuche umzusetzen. :]

TOX
 
 
Neue Frage »
Antworten »



Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »