AGB  ·  Datenschutz  ·  Impressum  







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

Ein bisschen lineare Algebra

Ein Thema von LDericher · begonnen am 1. Mär 2010 · letzter Beitrag vom 1. Mär 2010
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von LDericher
LDericher

Registriert seit: 29. Jan 2007
Ort: Erkelenz
224 Beiträge
 
Delphi 7 Enterprise
 
#1

Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:10
Also, eigentlich dürfte das kein Problem sein - habe ich mir gedacht...

Ich wollte mir einen Farb-Ring bauen; später will ich daraus auch ein Control machen. Was das Teil genau können soll, müsst ihr noch nicht wissen, denn es hakt schon deutlich vorher.

Ich will die Farbe jedes Pixels über den Winkel errechnen, und wenn ich den kennen würde, wäre das ganze auch kein Problem. Folgendermaßen gehe ich bis jetzt vor:

1. Ich zeichne einen schwarzen Ring auf weißem Grund. (Canvas.Ellipse, temporäres BMP)
2. Ich durchlaufe die einzelnen Pixel vom Bild (im Moment noch über Canvas.Pixels, aber das werde ich noch rausoptimieren) und schreibe auf das Zielcanvas (das von der Form) den berechneten Farbwert, sofern ich kein weißes Pixel habe.

Den Farbwert will ich berechnen, indem ich den Winkel "alpha" verarbeite (siehe angefügte Skizze).
Natürlich sind N, Z und M bekannt.

Meine Überlegung ist nun so:
Code:
N(aRadius, 0).
M(aRadius, aRadius).
Z(x, y).
n = N - M = (0, -aRadius).
z = Z - M = (x - aRadius, y - aRadius).
alpha = arccos( (n * z) / (|n| * |z|) ).
wobei n * z für das Skalarprodukt und |n| für den Betrag/die Länge steht.

In Quellcode habe ich das ganze nun so versucht umzusetzen:
Delphi-Quellcode:
function ScalarProduct(var pVec1, pVec2:TPoint):integer;
begin
Result:=(pVec1.X * pVec2.X) + (pVec1.Y * pVec2.Y);
end;

function Length(var pVec:TPoint):Extended;
begin
Result:=Sqrt(Sqr(pVec.X)+Sqr(pVec.Y));
end;
{...}
function TColorRing.getColor(X, Y: integer): TColor;
var
  vecN,
  vecZ:TPoint;
  Angle:Extended;
begin
vecN:=Point(0, -aRadius);
vecZ:=Point(X-aRadius, Y-aRadius);
Angle:=ScalarProduct(vecN, vecZ)/(Length(vecN)*Length(vecZ));
Angle:=ArcCos(Angle);
Result:=trunc(Angle*(360/Pi)); // Sollte Werte zwischen 0 und 360 geben.
end;
Aber leider scheint das ganze nicht so funktionieren zu wollen, wie ich das gern hätte, denn Result liegt zwar richtigerweise zwischen 0 und 360, aber die Werte sind "gespiegelt", also der rechte Halbkreis liefert 0..360 genau wie der Linke. Ich hätte aber gern oben die 0/360, rechts die 90, unten die 180 und links die 270; der Rest entsprechend dazwischen...

Wer kann mir helfen, meinen Fehler zu finden?

Gruß,
Euer LDer
Angehängte Grafiken
Dateityp: bmp skizze_183.bmp (403,3 KB, 17x aufgerufen)
"Clicking this button you agree with our Verantwortungsverzicht und Abkommen."
Zitat von Ein unentschlossener Programmierer:
Enabled:=true or false or true or false or true or false;
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#2

Re: Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:15
Pi entspricht 180° nicht 360°!
  Mit Zitat antworten Zitat
Benutzerbild von LDericher
LDericher

Registriert seit: 29. Jan 2007
Ort: Erkelenz
224 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:17
Zitat von gammatester:
Pi entspricht 180° nicht 360°!
Wah!
Okay, danke, jetzt hab ich schonmal die 180 unten, das ist schonmal gut, danke
Aber jetzt ist immer noch die 90 links UND rechts, aber die soll nur rechts sein, links muss die 270 hin. Ein schöner Kreis solls werden, nicht zwei Halbkreise... irgendwo hakts da noch
"Clicking this button you agree with our Verantwortungsverzicht und Abkommen."
Zitat von Ein unentschlossener Programmierer:
Enabled:=true or false or true or false or true or false;
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:27
Das Problem ist, dass diese Art der Winkelbestimmung immer zum kleineren Winkel zwischen 2 Vektoren führt. Schau dir mal ATan2() an!
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

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

Re: Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:29
Kennst du Polarkooradinaten?

Um den Winkel alpha zu ermitteln: alpha = Math.arctan2(z.Y, z.X)

Der Winkel ist allerdings mathematisch - also gleich null wenn der Punkt ganz rechts liegt und dann im Uhrzeigersinn positiv (da ja die y-Achse nach unten geht)
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#6

Re: Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:30
arccos bildet [-1..1] auf [0..Pi] ab, also wirst Du niemals Winkel größer als 180° erhalten. Dies Situation muß Deine übergeordnete Logik behandeln. Vielleicht so (ohne Gewähr): wenn Winkel(n,z) > 180, dann 360 - Winkel(z,n), genaueres mußt Du eventuell in Deiner LA-Quelle nachlesen.
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#7

Re: Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:34
Zitat von jfheins:
Kennst du Polarkooradinaten?

Um den Winkel alpha zu ermitteln: alpha = Math.arctan2(z.Y, z.X)
Das ist aber nicht alpha, sondern der Winkel zwischen x-Achse und z!
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

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

Re: Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:39
Zitat von gammatester:
Zitat von jfheins:
Kennst du Polarkooradinaten?

Um den Winkel alpha zu ermitteln: alpha = Math.arctan2(z.Y, z.X)
Das ist aber nicht alpha, sondern der Winkel zwischen x-Achse und z!
Ich hab ja auch extra dazugeschriben, dass der Winkel dann null ist, wenn der Punkt waagerecht rechts des Mittelpunkts liegt. Einen konstanten Winkel zu addieren sollte noch machbar sein ...

Aber, okay, hier die korrigierte Formel:

alpha = Math.arctan2(z.Y, z.X) + PI/2; // bzw. 90°
if alpha < 0 then alpha = alpha + 2*PI; // Danach ist alpha nicht mehr negativ
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#9

Re: Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:41
atan2()-pi/2 sollte das fixen, wobei man dann natürlich ein Auge auf alpha<0 haben muss. Falls links/rechts dann noch vertauscht sind, den 2. Parameter negieren.

Edit: Negative Winkel kommen eh vor, stimmt ja. Die muss man also eh schon zurecht zuppeln
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von LDericher
LDericher

Registriert seit: 29. Jan 2007
Ort: Erkelenz
224 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Ein bisschen lineare Algebra

  Alt 1. Mär 2010, 12:42
Das mit [0..Pi] ist mir dann auch aufgefallen... aber der arctan2 ist genau das was ich gebraucht habe!

Also hab ich was gebastelt, das genau das tut, was ich will:
Delphi-Quellcode:
function TColorRing.getAngle(X, Y: integer): integer;
var
  vecZ:TPoint;
  Angle:Extended;
begin
vecZ:=Point(X-aRadius, Y-aRadius);
Angle:=Math.ArcTan2(vecZ.X, vecZ.Y);
Result:=trunc(Angle*(180/Pi));
Result:=180-Result;
end;
Danke für eure Mühen!

Euer LDer
"Clicking this button you agree with our Verantwortungsverzicht und Abkommen."
Zitat von Ein unentschlossener Programmierer:
Enabled:=true or false or true or false or true or false;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 09:56 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