AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Optische Verkürzung

Ein Thema von CarpeNoctem · begonnen am 17. Nov 2009 · letzter Beitrag vom 18. Nov 2009
Antwort Antwort
CarpeNoctem

Registriert seit: 16. Nov 2009
2 Beiträge
 
#1

Optische Verkürzung

  Alt 17. Nov 2009, 00:50
Hallo.
Erstmal vorweg: Mein Problem ist mathematisch.
Und Zwar möchte ich auf ein Image mit Canvas ein Schachbrett zeichnen, allerdings optisch 3 Dimensional. Jetzt hab ich aber Probleme mit dem Faktor, um den der Y-Wert abnimmt, wenn man in die Tiefe geht.

Mein Ansatz:

Delphi-Quellcode:
Procedure TForm1.Gitter;
var i:Integer;
    a,b,a1,b1,x,y:Extended;
begin
  Image.Canvas.Pen.Color := rgb(0, 0, 0);
  b := Image.Width;
  a := 1/2 * sqrt(power(Image.Height,2) + power((1/2 * Image.Width),2));
  for I := 0 to 10 do
  begin
    Image.Canvas.MoveTo(i * round(b / 10), Image.Height);
    Image.Canvas.LineTo(round(I * b / 20 + Image.Height / 4), round(Image.Height / 2));
  end;
  for I := 0 to 10 do
  begin
      x := 1/2 * (Image.Width - b);
      b1 := b / 10;
      a1 := a * (x / b);
      y := sqrt(power(a1,2) - power((1/2 * x),2));
      Image.Canvas.MoveTo(round(x),round(Image.Height - y));
      Image.Canvas.LineTo(Image.Width, round(Image.Height - y));
      b := b - b1;
      a := a - a1;
  end;
end;
Allerdings bekomme ich beim Ausführen eine Fehlermeldung mit dem Inhalt: "ungültige Gleitkommaoperation". Soweit ich weiß heist das ja, dass ich durch 0 teilen würde oder eine Variable nicht richtig initialisiert worden ist.

Ich wäre dankbar für einen Lösungsvorschlag oder verbesserung des Ansatzes.

MFG
  Mit Zitat antworten Zitat
v2afrank

Registriert seit: 9. Mai 2005
Ort: Bocholt
573 Beiträge
 
Delphi XE2 Professional
 
#2

Re: Optische Verkürzung

  Alt 17. Nov 2009, 07:24
Das Problem ist diese Zeile
y := sqrt(power(a1,2) - power((1/2 * x),2)); Je nach Größe des Images wird power((1/2 * x),2) größer als power(a1,2), so dass Du die Wurzel aus einer negativen Zahl ziehst
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#3

Re: Optische Verkürzung

  Alt 17. Nov 2009, 09:17
Ich würde an das Problem folgendermaßen drangehen (hab im Moment übrigens ein sehr ähnliches Problem, nur ohne Schachbrett)

1. Trapezverzerrung (damit die Linien zu einem Fluchtpunkt zusammenlaufen)
2. Drehung um die waagerechte Achse, sodass die Ebene schief im Raum liegt.
3. Parallelproketion, um wieder ein 2-dimensionales Bild zu bekommen
Die ersten beiden Schritte sollten auch vertauschbar sein.

Jetzt ist da natürlich erstmal die Frage, ob du dir was darunter vorstellen kannst
  Mit Zitat antworten Zitat
CarpeNoctem

Registriert seit: 16. Nov 2009
2 Beiträge
 
#4

Re: Optische Verkürzung

  Alt 17. Nov 2009, 23:09
Erst einmal Danke für die Antworten.

Die Sache wird wohl etwas komplizierter, als ich angenommen habe ...

Zitat von jfheins:
1. Trapezverzerrung (damit die Linien zu einem Fluchtpunkt zusammenlaufen)
2. Drehung um die waagerechte Achse, sodass die Ebene schief im Raum liegt.
3. Parallelproketion, um wieder ein 2-dimensionales Bild zu bekommen
Die ersten beiden Schritte sollten auch vertauschbar sein.

Jetzt ist da natürlich erstmal die Frage, ob du dir was darunter vorstellen kannst
Also zumindestens Punkt 1 und 2 kann ich mir vorstellen - hoff ich (siehe Anhang) aber den 3. Punkt versteh ich leider nicht so direkt .
Miniaturansicht angehängter Grafiken
gitter_389.png  
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#5

Re: Optische Verkürzung

  Alt 18. Nov 2009, 10:43
Hab dir da mal was gecodet

Ist jetzt zwar Q&D und es hat auch ein bisschen gedauert bis das einigermaßen hingehauen hat - aber es dürfte deinen Anforderungen schon nahe kommen

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Test_1
{
    public partial class Form1 : Form
    {
        RectangleF Outline;
        byte Rows = 8;
        byte Cols = 8;

        Pen pen;

        public Form1()
        {
            InitializeComponent();

            pen = new Pen(Color.Black, 2);

            Outline = new RectangleF(-200, 0, 400, 400);
        }

        private PointF DisplayTransform(PointF coord)
        {
            PointF Result = new PointF();
            Result.X = coord.X + pictureBox1.Width / 2;
            Result.Y = coord.Y + pictureBox1.Height * 0.8f;
            return Result;
        }

        private PointF Transform(PointF coord)
        {
            // Trapezverzerrung

            coord.X = coord.X * ( 1 - coord.Y * ((float)trackBar3.Value / 10000f));

            // Rotation um die x-Achse
            // gleichzeitug: Parallelprojektion
            // (Im Grunde geht man kurz in den 3D-Raum um dann die Z-Komponente wegzuwerfen,
            // da kann man sich die aber auch direkt sparen)
            coord.Y = coord.Y * (float)Math.Sin(trackBar1.Value * Math.PI / 180);

            return coord;
        }

        private void Transform(ref PointF[] coords)
        {
            for (int i = 0; i < coords.Length; i++)
            {
                coords[i] = DisplayTransform(Transform(coords[i]));
            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            float colwidth = Outline.Width / (float)Cols;
            float rowheight = Outline.Height / (float)Rows;

            PointF[] Feld = new PointF[4];

            Brush farbe;

            for (int row = 0; row < Rows; row++)
            {
                for (int col = 0; col < Cols; col++)
                {
                    var left = Outline.Left + col * colwidth;
                    var top = Outline.Top + row * rowheight;

                    Feld[0] = new PointF(left, top);
                    Feld[1] = new PointF(left + colwidth, top);
                    Feld[2] = new PointF(left + colwidth, top + rowheight);
                    Feld[3] = new PointF(left, top + rowheight);

                    Transform(ref Feld);

                    if ((row + col + 1) % 2 == 0)
                        farbe = Brushes.Black;
                    else
                        farbe = Brushes.White;

                    e.Graphics.FillPolygon(farbe, Feld);
                }
            }


            Feld[0] = new PointF(Outline.Left, Outline.Top);
            Feld[1] = new PointF(Outline.Left + Outline.Width, Outline.Top);
            Feld[2] = new PointF(Outline.Left + Outline.Width, Outline.Top + Outline.Height);
            Feld[3] = new PointF(Outline.Left, Outline.Top + Outline.Height);

            Transform(ref Feld);

            e.Graphics.DrawPolygon(pen, Feld);
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            var a = 10 * Math.Cos((360 - trackBar1.Value) * Math.PI / 180);
            trackBar3.Value = (int)a;
            pictureBox1.Invalidate();
        }

        private void trackBar3_Scroll(object sender, EventArgs e)
        {
            pictureBox1.Invalidate();

        }
        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            pictureBox1.Invalidate();
        } 
    }
}
Der ober Schieber steuert die "Drehung" und der untere steuert die Trapezverzerrung. Um eine ordentliche Perspektive hinzubekommen müssen diese beiden passend gekoppelt sein. Hab das jetzt einfach mal probiert (wenn man den oberen Schiber bewegt, wird der untere auch angepasst)

Programm im Anahng
Angehängte Dateien
Dateityp: exe test_1_149.exe (10,0 KB, 2x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz