Jump to content

Objekt mit Aktion drehen


BauerHeini

Empfohlene Beiträge

Hallo Community,

ich möchte eine Beschriftung, also ein Objekt, per Aktion drehen. Anscheinend geht das nur mit LUA. Der Befehl "$("Beschriftung").rotation = {0, 0, 0, 120, 0} funktioniert nicht, sondern bringt die Fehlermeldung "Skriptfehler (18)".

Hat jemand eine Lösung?

Mit freundlichen Grüßen
Heinz

Link zu diesem Kommentar
Auf anderen Seiten teilen

$("Beschriftung").transformation.rotation = {0, 0, 0, 120.0}

kein " vor $ und Vorsicht: in Lua kein Dezimalkomma, sondern Dezimalpunkt. Es dürfen nur vier Werte sein.
Diese Werte sind aber ein Quaternion, mit 120.0 als Winkel geht's so nicht. Willst Du einfach nur Z um 120° drehen?

kleine Formelsammlung (kopier sie Dir nach "Ereignisse" -> Skript)

function RadToDeg(n) -- Bogenmaß (Radian) -> Grad
  return n*180/3.1415927
end

function DegToRad(n) -- Grad -> Bogenmaß (Radian)
  return n*3.1415927/180
end

function ToEulerAngles(q)
  local angles = { x=0, y=0, z=0 }   -- roll, pitch, yaw

  -- roll (x-axis rotation)
  local sinr_cosp = 2 * (q.w * q.x + q.y * q.z)
  local cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y)
  angles.x = math.atan(sinr_cosp, cosr_cosp) -- roll

  -- pitch (y-axis rotation)
  local sinp = 2 * (q.w * q.y - q.z * q.x)
  if math.abs(sinp) >= 1 then
    angles.y = 1 -- copysign(M_PI / 2, sinp); // use 90 degrees if out of range
  else
    angles.y = math.asin(sinp) -- pitch
  end

  -- yaw (z-axis rotation)
  local siny_cosp = 2 * (q.w * q.z + q.x * q.y)
  local cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z)
  angles.z = math.atan(siny_cosp, cosy_cosp) -- yaw

  -- Radian to Degree
  angles.x = RadToDeg(angles.x)
  angles.y = RadToDeg(angles.y)
  angles.z = RadToDeg(angles.z)

  return angles
end

function ToQuaternion(yaw, pitch, roll) -- yaw (Z), pitch (Y), roll (X), input in Degree
  yaw = DegToRad(yaw)
  pitch = DegToRad(pitch)
  roll = DegToRad(roll)
  local cy = math.cos(yaw * 0.5)
  local sy = math.sin(yaw * 0.5)
  local cp = math.cos(pitch * 0.5)
  local sp = math.sin(pitch * 0.5)
  local cr = math.cos(roll * 0.5)
  local sr = math.sin(roll * 0.5)

  local q = {}
  q.w = cy * cp * cr + sy * sp * sr
  q.x = cy * cp * sr - sy * sp * cr
  q.y = sy * cp * sr + cy * sp * cr
  q.z = sy * cp * cr - cy * sp * sr

  return q
end

function NormQ(q)
  local l = math.sqrt(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w)
  if l ~= 0 then
    q.x = q.x / l
    q.y = q.y / l
    q.z = q.z / l
  end
  return q
end

und dann
$("Beschriftung").transformation.rotation = NormQ(ToQuaternion(120.0, 0.0, 0.0))

oder schau mal, wie rotateZ funktioniert.

Gruß
  Andy

Bearbeitet von Andy
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Andy,

vielen Dank für die schnelle Antwort. Mit '$("Beschriftung").transformation.rotation = NormQ(ToQuaternion(120.0, 0.0, 0.0))' kommt wieder 'Skriptfehler (18): attempt to call a nil value (global 'ToQuaternion')'.

Bei '$("Beschriftung").transformation.rotateZ = NormQ(ToQuaternion(120.0, 0.0, 0.0))' kommt 'Skriptfehler (28): attempt to call a nil value (global 'ToQuaternion')'.

Bei '$("Beschriftung").rotateZ = NormQ(ToQuaternion(120.0, 0.0, 0.0))' kommt dieselbe Meldung.

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich denke mal, dass Du die kleine Funktionsbibliothek nicht kopiert hast! Es geht schon, siehe:

 

rotation.mbp

Beachte Ereignisse -> Skript! Da liegt die Bibliothek.

Wir sind von V4 her eigentlich nur Grad-Winkel gewohnt. Neo hätte hier besser sowohl Bogenmaß, als auch die Quaternionen 'verstecken' können und anwenderfreundlichere Funktionen zur Verfügung stellen können. Es ist mir klar, dass für einige Dinge Quaternionen vorteilhafter sind, aber dieses Gebilde haben nun die wenigsten in der Schule gehabt. Also, zumindest mal rotateX, rotateY, rotateZ mit einem einfachen Grad-Winkel hätte es getan.

Bearbeitet von Andy
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

mit folgenden zwei Zeilen kannst du auch ohne Hilfsfunktionen ein Objekt um eine Achse drehen:

$("Beschriftung").transformation.rotation = {x = 0, y = 0, z = 0, w = 1}
$("Beschriftung").transformation:rotateZ(math.rad(120))

Lässt du die erste Zeile weg, dreht sich deine Beschriftung bei jedem Klick um weitere 120 Grad.

Viele Grüße,

Neo

Link zu diesem Kommentar
Auf anderen Seiten teilen

Tja, gewußt wie ;)

Das mit dem Doppelpunkt war mir nicht klar, deswegen habe ich diese Funktionen nicht im Hilfetext gefunden. Wußte aber, dass sie da sind...
Aber auch dann hätte ich nicht geahnt, dass ja erstmal ein initialisierendes Einheitsquat zugewiesen werden muß. Nach Deinem Beispiel ist das offensichtlich.
Vielleicht diesen Zweizeiler mit in den Hilfetext bringen, @Neo

beste Grüße
  Andy

Bearbeitet von Andy
Link zu diesem Kommentar
Auf anderen Seiten teilen

Vielen Dank für die Antworten. Vielleicht sollte ich mal sagen, was ich eigentlich erreichen will.

Ich möchte einen Pfeil '->' in einem Beschriftungsobjekt je nach Schalterstellung drehen und zwar einmal nach unten links (z=-120°) und einmal nach unten rechts (z=-60°).

Wenn ich eingebe: $("Beschriftung").transformation.rotation = {x = 0, y = 0, z = -60, w = 1}, kommt die Fehlermeldung 'attempt to index a nil value' und es passiert nichts. Was mache ich falsch?

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du machst mit der Zeile den gleichen Fehler immer noch. x,y,z sind NICHT die Winkel!
Neo's Beispiel ist doch sonnenklar. Da braucht es sogar die Funktionsbibliothek nicht.
Verwende es einmal mit -120 und das andere mal mit -60.
Und das mit dem nil-value .. gibt es das Objekt "Beschriftung" überhaupt noch?

Link zu diesem Kommentar
Auf anderen Seiten teilen

--[[
  This is the way to rotate an object
  that Neo has suggested:
  1. Force the object to zero degrees
  2. Rotate by required angle
--]]

   if track.state == 0 then
      $("Arrow2").transformation.rotation = { x = 0 , y = 0 , z = 0 , w = 1 }
      $("Arrow2").transformation:rotateZ(math.rad(-120))
   end


   if track.state == 1 then
      $("Arrow2").transformation.rotation = { x = 0 , y = 0 , z = 0 , w = 1 }
      $("Arrow2").transformation:rotateZ(math.rad(-60))
   end

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich komme nicht weiter. Dies ist mein Skript...

if $("Kippschalter links").state == 0 then
  $("Beschriftung links").text = "->"
  $("Beschriftung rechts").text = "<-"
  $("Beschriftung links Status").text = "0"
  $("Beschriftung").transformation.rotation = { x = 0 , y = 0 , z = 0 , w = 1 }
  $("Beschriftung").transformation:rotateZ(math.rad(-120))
elseif $("Kippschalter links").state == 1 then
  $("Beschriftung rechts").text = "R"
  $("Beschriftung links").text = "->"
  $("Beschriftung links Status").text = "1"
  $("Beschriftung").transformation.rotation = {x = 0, y = 0, z = 0, w = 1}
  $("Beschriftung").transformation:rotateZ(math.rad(-60))
elseif $("Kippschalter links").state == 2 then
  $("Beschriftung links").text = "->"
  $("Beschriftung rechts").text = "R"
  $("Beschriftung links Status").text = "2"
  $("Beschriftung").transformation.rotation = {x = 0, y = 0, z = 0, w = 1}
  $("Beschriftung").transformation:rotateZ(math.rad(-60))

elseif $("Kippschalter links").state == 3 then
  $("Beschriftung links").text = "L"
  $("Beschriftung rechts").text = "<-"
  $("Beschriftung links Status").text = "3"
  $("Beschriftung").transformation.rotation = {x = 0, y = 0, z = 0, w = 1}
  $("Beschriftung").transformation:rotateZ(math.rad(-120))
end

...und das sind die Meldungen:

[13:45:04] Weiche schaltet -> Abzweigung, 3
[13:45:04] Schalter wird betätigt -> Kippschalter links, 3
[13:45:04]     Schalter wird betätigt
[13:45:04]         attempt to index a nil value

bei allen Schalterstellungen gleich (also 0..3)

Link zu diesem Kommentar
Auf anderen Seiten teilen

@heinz.mehlen, bitte check nochmal durch, ob Deine Objekte wirklich genau diese Namen haben. Insbesondere "Beschriftung". Da habe ich beim letzten Mal schon vermutet, dass da was nicht stimmt. nil heißt in dem Fall, dass er ein Objekt nicht findet. Alle anderen Anweisungen sind sonst syntaktisch korrekt.

Eine Fehlermöglichkeit ist auch: "Beschriftung" wird für mehrere Objekte verwendet. Hätte also ein * hinterm Namen, wenn Du das Objekt anklickst. Dann ist er etwas ratlos. Da muß ein eindeutiger Name her.

Ob das dann bei mehrfachem Schalten so wird, wie Du's willst, lassen wir mal offen. Erst müssen wir dem nil das Wasser abgraben.
Wenn Du nach dem Fehler noch einmal in das Skript zurückgehst, hat er dann eine Anweisung verändert und $("") draus gemacht? Da macht er, wenn er ein Objekt nicht findet.

Gruß
  Andy

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Andy,

ich glaube, wir sind auf dem richtigen Weg. Ich habe eine einfache Testfunktion erstellt und es kam wieder diese Meldung. Dann habe ich eine vorhandene Ereignissteuerung gesehen, deren Elemente (Objekte) ich gelöscht hatte. Nach dem Löschen der Funktion kam die Fehlermeldung nicht mehr.

Dann wieder, in froher Hoffnung, die eigentliche Ereignissteuerung aufgerufen und dann kam eine etwas detailliertere Meldung...

Skriptfehler (19): attempt to index a nil value

... dann habe ich alle anderen Befehle auf Kommentar gesetzt, und dann kam diese Meldung...

Skriptfehler (35): attempt to index a nil value

Hier noch einmal das Skript:

if $("Kippschalter links").state == 0 then
--[[  $("Beschriftung links").text = "->"
  $("Beschriftung rechts").text = "<-"
  $("Beschriftung links Status").text = "0"
--]]
  $("").transformation.rotation = { x = 0 , y = 0 , z = 0 , w = 1 }
  $("").transformation:rotateZ(math.rad(-120))
elseif $("Kippschalter links").state == 1 then
--[[  $("Beschriftung rechts").text = "R"
  $("Beschriftung links").text = "->"
  $("Beschriftung links Status").text = "1"
--]]
  $("").transformation.rotation = {x = 0, y = 0, z = 0, w = 1}
  $("").transformation:rotateZ(math.rad(-60))
elseif $("Kippschalter links").state == 2 then
--[[  $("Beschriftung links").text = "->"
  $("Beschriftung rechts").text = "R"
  $("Beschriftung links Status").text = "2"
--]]
  $("").transformation.rotation = {x = 0, y = 0, z = 0, w = 1}
  $("").transformation:rotateZ(math.rad(-60))
elseif $("Kippschalter links").state == 3 then
--[[  $("Beschriftung links").text = "L"
  $("Beschriftung rechts").text = "<-"
  $("Beschriftung links Status").text = "3"
--]]
  $("").transformation.rotation = {x = 0, y = 0, z = 0, w = 1}
  $("").transformation:rotateZ(math.rad(-120))
end

Gibt es irgendwo eine Möglichkeit die Fehlermeldungen zu identifizieren?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ganz offensichtlich. Es gibt/gab definitiv das Objekt "Beschriftung" nicht. Er hat's dann rausgelöscht und $("") draus gemacht.
Meine allererste Vermutung hat sich bestätigt. Jetzt schau endlich mal, wie das Ding wirklich heißt und dann füge den Namen überall zwischen die "" ein. Und paß' auf, dass es den Namen nicht zweimal gibt. Dann teste nochmal.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren

Du musst ein Benutzerkonto besitzen, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen.

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde dich hier an.

Jetzt anmelden
×
×
  • Neu erstellen...