![]() |
Richtungs bzw. Vektorpfeil zeichnen
Hallo.
Ich verfolge Dinge über eine Webcam um will die Bewegung durch Pfeile darstellen. Das Ganze soll dann auf einem Bitmap ausgegeben werden. Ich habe den Start- und Endpunkt und kann sozusagen die Grundlinie des Pfeils zeichnen:
Delphi-Quellcode:
die differenz zurletzten x/y position kann errechnet werden über
FBitmap.Canvas.MoveTo(mid_old.x, mid_old.y);
FBitmap.Canvas.LineTo(mid.x, mid.y);
Delphi-Quellcode:
hat einer ne idee, wie ich da nen pfeil draus machen kann? bzw. nen anderen lösungsansatz?
mid.x - mid_old.x
mid.y - mid_old.y sollte relativ fix gehen, da ein paarmal die sekunde aktualisiert wird. |
Re: Richtungs bzw. Vektorpfeil zeichnen
mit dem dx und dy hast du den Winkel alpha des Pfeiles zur horizontalen. Jetzt zeichnest du von der Spitze deines Pfeiles ausgehend zwei Striche mit passenden Winkeln. Wie das jetzt genau aussieht, will ich mir nicht überlegen, aber mit etwas hinzeichnen undTrigonometrie ist das zu machen. Auf die geschiwndigkeit brauchst du dabei überhaupt nicht zu achten. Eine sinus Berechnung braucht bei mir etwa 200 Ticks und wenn du einen GigaHertz-Rechner hast, kannst du mal kurz ausrechnen, wie viele Sinusse da pro Sekunde berechnet werden können :)
|
Re: Richtungs bzw. Vektorpfeil zeichnen
Die entsprechende Mathematik:
tan alpha = m m = (y2-y1) / (x2-x1) <-> alpha = arctan((y2-y1) / (x2-x1)); dann addierst du zu alpha 30° für eine seite der pfeilspitze, ziehst von alpha 30° ab für die andere seite. wir setzen l = länge der pfeilspitze. die koordinaten rechnest du dann mit sinus und cosinus aus: x = cos(alpha±30°) * l y = sin(alpha±30°) * l |
Re: Richtungs bzw. Vektorpfeil zeichnen
also danke erstmal für die antworten.
ja, mit der mathematik is nich so dolle bei mir :-/. glaube ich habe das nen bissel falsch umgesetzt, weil ich den anfang nicht so ganz kapiere:
Delphi-Quellcode:
dachte er zeichnet mir jetzt eine seite aber bei den werten kommt quark raus :-(
if (x1 - x2)<>0 then a:=arctan((y1 - y2) / (x1 - x2));
FBitmap.Canvas.LineTo(Round(cos(a-30)), Round(sin(a-30))); |
Re: Richtungs bzw. Vektorpfeil zeichnen
Die Koordinaten sind natürlich Offsets!
Delphi-Quellcode:
Damit sollte er das komplette Dreieck zeichnen.
if (x1 - x2)<>0 then a:=arctan((y1 - y2) / (x1 - x2));
//FBitmap.Canvas.MoveTo(x2,y2); //Der Zeichenstift sollte ja noch am Ende des Pfeils stehen. FBitmap.Canvas.LineTo(x2-Round(cos(a-30)*3), Round(y2-sin(a-30)*3)); FBitmap.Canvas.LineTo(x2-Round(cos(a+30)*3), Round(y2-sin(a+30)*3)); FBitmap.Canvas.LineTo(x2,y2); |
Re: Richtungs bzw. Vektorpfeil zeichnen
hmm habs mit mehreren offsets getestet aber kommt nur quark bei raus.
die verschiebung für x und y liegt jeweils bei ca. -20 bis +20. hier mal der originalcode villeicht bin ich ja blind.
Delphi-Quellcode:
so sieht das z.b. im mom bei ner handbewegung nach oben rechts aus (blaue linien):
FBitmapOld2.Canvas.MoveTo(mid_old.x, mid_old.y);
FBitmapOld2.Canvas.LineTo(mid.x, mid.y); {die linie wird korrekt gezeichnet} if (mid.x - mid_old.x)<>0 then a:=arctan((mid.y - mid_old.y) / (mid.x - mid_old.x)); FBitmapOld2.Canvas.LineTo(Round(cos(a-30)*3), Round(sin(a-30)*3));{hier gehts dann ab richtung 0/0} FBitmapOld2.Canvas.LineTo(Round(cos(a-30)*3), Round(sin(a-30)*3)); FBitmapOld2.Canvas.LineTo(mid.x, mid.y); ![]() |
Re: Richtungs bzw. Vektorpfeil zeichnen
Liste der Anhänge anzeigen (Anzahl: 1)
Hm. Ich verpack das mal in eine Prozedur, damit wir da nicht eventuell irgendwelche Variablen verwechseln:
Delphi-Quellcode:
Hrmpf.
function degtorad(angle : Double) : Double;
begin result := pi * angle / 180; end; function radtodeg(angle : Double) : Double; begin result := 180 * angle / pi; end; procedure DrawArrow(Canvas: TCanvas; StartP, EndP: TPoint); const OffsetAngle = 30; ArrowLength = 10; var LineAngle: Integer; ArrowLine1,ArrowLine2: TPoint; begin LineAngle := Round(RadToDeg(arctan((EndP.Y-StartP.Y) div (EndP.X - StartP.X)))); ArrowLine1.X := Round(EndP.X + cos(DegToRad(LineAngle+OffsetAngle))*ArrowLength); ArrowLine1.Y := Round(EndP.Y + sin(DegToRad(LineAngle+OffsetAngle))*ArrowLength); ArrowLine2.X := Round(EndP.X + cos(DegToRad(LineAngle-OffsetAngle))*ArrowLength); ArrowLine2.Y := Round(EndP.Y + sin(DegToRad(LineAngle-OffsetAngle))*ArrowLength); Canvas.MoveTo(StartP.X,StartP.Y); Canvas.LineTo(EndP.X,EndP.Y); Canvas.LineTo(ArrowLine1.X,ArrowLine1.Y); Canvas.LineTo(ArrowLine2.X,ArrowLine2.Y); Canvas.LineTo(EndP.X,EndP.Y); end; Macht immer noch nicht wirklich was er machen soll. EDIT: Update. Macht inzwischen immerhin Sachen, die wie Pfeile aussehen, aber ich muss anscheinend doch Unterscheidungen für die einzelnen Quadranten einbauen. EDIT: Kleine Demo gebastelt. |
Re: Richtungs bzw. Vektorpfeil zeichnen
Delphi-Quellcode:
procedure ArrowTo(RC:TCanvas;xa,ya,xe,ye,pb,pl:integer;Fill:boolean);
var m,t,sqm : real; x1,y1,x2,y2,xs,ys,la : real; begin la:=sqrt(sqr(xe-xa)+sqr(ye-ya)); if la<0.01 then exit; t:=(la-pl)/la; xs:=xa+t*(xe-xa); if xe<>xa then begin m:=(ye-ya)/(xe-xa); ys:=ya+t*m*(xe-xa); if m<>0 then begin sqm:=sqrt(1+1/sqr(m)); x1:=xs+pb/sqm; y1:=ys-(x1-xs)/m; x2:=xs-pb/sqm; y2:=ys-(x2-xs)/m; end else begin x1:=xs; x2:=xs; y1:=ys+pb/1.0; y2:=ys-pb/1.0; end; end else begin xs:=xa; ys:=ya+t*(ye-ya); x1:=xs-pb/1.0; x2:=xs+pb/1.0; y1:=ys; y2:=ys; end; RC.MoveTo(xa,ya); RC.LineTo(round(xs),round(ys)); if Fill then begin RC.Brush.Color:=RC.Pen.Color; RC.Brush.Style:=bsSolid; RC.Polygon([Point(xe,ye),Point(round(x1),round(y1)), Point(round(x2),round(y2)),Point(xe,ye)]); end else RC.Polyline([Point(xe,ye),Point(round(x1),round(y1)), Point(round(x2),round(y2)),Point(xe,ye)]); end; ![]() danke für die mithilfe und inspiration! :-) |
Re: Richtungs bzw. Vektorpfeil zeichnen
Zitat:
Wie bekommst du denn bis dahin schonmal die position bzw richtungsvektoren aus dem Webcam-Bild? |
Re: Richtungs bzw. Vektorpfeil zeichnen
Also ich würde die Sache so angehen:
1.) ein " ![]() 2.) Also muss man erstmal einen Pfeil im Ursprung konstruieren. Die Pfeilspitze sollte (muss aber nicht) im Ursprung sitzen. Der Pfeil muss auf kariertem Papier aufgezeichnet und die Koordinaten der einzelnen Punkte abenommen werden.
Delphi-Quellcode:
3.) da reicht aber noch nicht. Der Pfeil muss vor dem Zeichnen noch gedreht und anschliesend verschoben werden.
Pfeil: array[1..7] of TPoint;
pfeil[1] := Point(x1, y1); .... canvas.Polygon(Pfeil); siehe Code-Library: ![]() Wie man sieht, ist diese Technik besser als die bisherigen Vorschläge, da man so nicht nur Pfeile, sondern auch Kreuze und andere Symbole zeichen kann. |
Re: Richtungs bzw. Vektorpfeil zeichnen
Zitat:
würde mich freuen, wenn jemand mit einer Webcam das tool mal testen könnte: ![]() wichtig: wenn bei dem difference kram was schief geht, dann solltet ihr unter format settings mal andere kompressionen probieren. mit einem klick auf "Difference" werden bewegungen visualisiert. danach kann man auf Track klicken, dann kommt der erwähnte bewegungspfeil und eine box hinzu. mit der Sound checkbox wird die bewegung mittels pc speake in töne umgewandelt. gibt noch einige reglerund spielereien wie color mapping usw. evtl. muss der maxdiff regler nach oben gestellt werden umdie schwelle vom bildrauschen oder anderen bewegungen zu filtern. Auf Anfrage könnt ihr gerne auch codeschnipsel haben Grüße Konrad |
Re: Richtungs bzw. Vektorpfeil zeichnen
Hallo Konrad,
Dein Tool funktioniert bei mir leider nicht, es meckert immer das es keinen passenden Codec gibt. So wie ich es verstehe, ist das so eine Art Motion Capturing. Daran wäre ich auch interessiert, da ich sowas auch machen wollte. Grüße Hans-Josef |
Re: Ich dreh durch! wie kann das sein - Problem beim Runden.
hallo hans-josef.
wenn du in meinem programm auf "format setting" klickst, welche auswahlmöglichkeiten hast du da bei dem mittleren reiter (pixel depth and compression) ? da einfachmal alle durchprobieren und nach jedem wechsel programm neustarten! habe gerade mal bei mir geschaut: wenn die cam schon verwendet wird, dann kommt diese fehlermeldung --> die webcam darf nicht geöffnet/von einem anderen programm bereits verwendet werden. viele grüße konrad |
Re: Richtungs bzw. Vektorpfeil zeichnen
Hallo Konrad,
danke für die schnelle Rückmeldung. Hatte ich schon probiert, ohne Erfolg. (Werden die Einstellungen denn überhaupt gespeichert?) Würde mir das gerne einmal ansehen, aber geht nicht. Mit anderen Tools funktioniert die Camera, wobei das ist keine Camera sondern ein Video-Grabber, sollte sich aber gleich verhalten. Kannst Du mir einmal Deinen Code posten? Grüße Hans-Josef |
AW: Richtungs bzw. Vektorpfeil zeichnen
Liste der Anhänge anzeigen (Anzahl: 1)
Es geht auch ohne sinus, cosinus,..:
Procedure DrawArrow( canvas:tCanvas; // canvas, auf dem gezeichnet werden soll x1,y1, // Koordinaten des Startpunktes x2,y2:integer; // Koordinaten des Endpunktes w:integer=5; // Breite (+- der Pfeilspitze l1:integer=20; // Länge der Pfeilspitze L2:integer=15 // Länge der Pfeilspitze in der Mitte ); var Len, lens,LenC:double; dx,dy:double; xs,ys,xc,yc:integer; poly:array[0..4] of tPoint; procedure setpoint(i:integer;x,y:integer); begin poly[i].X:=x; poly[i].Y:=y; end; begin Canvas.MoveTo(x1,y1); canvas.LineTo(x2,y2); len:=sqrt(sqr(x2-x1)+ sqr(y2-y1)); Lens:=len-L1; Lenc:=len-L2; dx:=(x2-x1)/Len; dy:=(y2-y1)/len; xs:=x1+round(dx*lens); ys:=y1+round(dy*lens); xc:=x1+round(dx*lenc); yc:=y1+round(dy*lenc); Setpoint(0,x2,y2); Setpoint(1,round(xs-dy*w), round(ys+dx*w)); Setpoint(2,xc,yc); Setpoint(3,round(xs+dy*w), round(ys-dx*w)); Setpoint(4,x2,y2); canvas.Polygon(poly); end; |
AW: Richtungs bzw. Vektorpfeil zeichnen
Auch beim Ausgraben von Leichen sollte man die Code-Tags verwenden. 8-)
Sherlock |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz