0 Daumen
291 Aufrufe

Frage:

Ich habe x und y Daten einer Autofahrt. Also Auto startet bei (0|0) nach 1 Sekunde befindet es sich auf stelle (2|-1) usw... Ich habe mir nun aus den Daten den zurückgelegten Weg als .svg Datei ausgeben lassen. Dort sehe ich nun den zurückgelegten Weg als eine Linie.

Ich möchte nun gerne meinen Code so erweitern dass in der .svg die Autofahrt simuliert wird. Also wenn ich die .svg öffne sollte die Linie jede Sekunde um den Wert x, y weiterfahren. Ist das überhaupt möglich? Falls ja wie mache ich dies?

Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main() {
  FILE *input_file, *svg_file;

  input_file = fopen("result.csv", "r");
  if (!input_file) {
      printf("fail to open result.csv\n");
      exit(1);
  }

  svg_file = fopen("path.svg", "w");
  if (!svg_file) {
      printf("fail to open path.svg\n");
      exit(1);
  }

  // write svg head
  const char *svg_head = "<svg xmlns='http://www.w3.org/2000/svg'><defs><rect width="10" height="10">;
  <animate attributeName="rx" values="0;5;0" dur="10s" repeatCount="indefinite" />
</rect>
</svg>\n";
  fputs(svg_head, svg_file);

  double min_x = 0.0, min_y = 0.0;

  char line[1024];
  while (fgets(line, sizeof(line), input_file)) {
      char *save = line;
      char *_x = strtok_r(line, ",", &save);
      double x = atof(_x);
      char *_y = strtok_r(NULL, ",", &save);
      double y = -atof(_y);
      if (x < min_x) min_x = x;
      if (y < min_y) min_y = y;
      fprintf(svg_file, "%f,%f\n", x, y);
  }

  // write svg tail
  const char *svg_tail = "'/></defs><use href='#line' x='%f' y='%f' fill='none' stroke='black' /></svg>";
  fprintf(svg_file, svg_tail, -min_x, -min_y);

  fclose(input_file);
  fclose(svg_file);
}

Avatar von

1 Antwort

0 Daumen

Antwort mit KI erzeugt

Autofahrt in C aus Daten visualisieren

Um die Autofahrt mit einer Linie in einer SVG-Datei zu simulieren, die jede Sekunde um den Wert \(x, y\) weiterfährt, müssen Sie den SVG-Code anpassen, um Animationen zu unterstützen. SVG bietet das <animate>-Element, mit dem Objekte über die Zeit verändert werden können. Leider unterstützt SVG nicht direkt die Animation entlang einer arbiträren Pfadkurve (wie Ihre Autofahrt) mit sich über die Zeit ändernden Geschwindigkeiten in so einer direkten Weise, ohne zusätzliches JavaScript oder komplexe Manipulationen.

Jedoch können wir eine Annäherung erreichen, indem wir eine Linie zeichnen, die den gesamten Pfad darstellt, und dann einen kleinen Kreis (oder ein anderes Symbol, das das Auto repräsentiert) entlang dieses Pfades animieren. Das bedeutet, dass der Pfad zunächst vollständig gezeichnet wird und anschließend das "Auto" darauf animiert wird.

Hier ist ein Überblick, wie Sie Ihren Code modifizieren können, um eine derartige Animation zu erzeugen:

- Pfad erstellen aus den x, y Datenpunkten, die den gesamten zurückgelegten Weg darstellen.
- Auto hinzufügen, das den Pfad entlang fährt. Dies kann durch ein Kreiselement (<circle>) symbolisiert werden, das entlang des Pfades animiert wird.

Update des Codes

Das grundlegende Vorgehen umfasst folgende Schritte:

1. Erstellung des SVG-Pfads aus Ihren x, y-Daten.
2. Hinzufügen eines <circle>-Elements und dessen Animation entlang des Pfades.

Hier ein Beispiel, wie der Code aussehen könnte:

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    FILE *input_file, *svg_file;

    input_file = fopen("result.csv", "r");
    if (!input_file) {
        printf("fail to open result.csv\n");
        exit(1);
    }

    svg_file = fopen("path.svg", "w");
    if (!svg_file) {
        printf("fail to open path.svg\n");
        exit(1);
    }

    // Schreiben des SVG-Headers
    fputs("<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 500 500' style='background-color:#FFF'>\n", svg_file);

    char line[1024];
    char path_data[10000] = "M ";
    
    while (fgets(line, sizeof(line), input_file)) {
        strcat(path_data, line);
        strcat(path_data, " ");
    }

    // Schreiben des Pfades
    fprintf(svg_file, "<path d='%s' fill='none' stroke='black'/>\n", path_data);

    // Kreis (Auto) hinzufügen
    fprintf(svg_file, "<circle r='5' fill='red'>\n");
    // Animation des Kreises entlang des Pfades
    fprintf(svg_file, "<animateMotion dur='10s' repeatCount='indefinite'>\n");
    fprintf(svg_file, "<mpath href='#path'/>\n");
    fprintf(svg_file, "</animateMotion>\n");
    fprintf(svg_file, "</circle>\n");

    // SVG abschließen
    fputs("</svg>\n", svg_file);

    fclose(input_file);
    fclose(svg_file);

    return 0;
}

Wichtige Anmerkungen zu diesem Beispiel:

- Dieser Code fügt alle x, y-Punkte aus Ihrer result.csv-Datei in einer einzigen M x1,y1 x2,y2 ... xn,yn-Anweisung zusammen. SVG nutzt diese Anweisung, um einen zusammenhängenden Pfad zu zeichnen.
- Der Kreis wird durch <circle> definiert und mittels <animateMotion> entlang dieses Pfades animiert. Derzeit wird dabei angenommen, dass #path die ID des Pfades ist, welches in diesem Code-Beispiel fehlt. Sie müssen also id='path' zu Ihrem <path>-Element hinzufügen oder die Animation entsprechend Ihrer Implementierung anpassen.

Bitte beachten Sie, dass dieser Code nur als Ausgangspunkt dient und angepasst werden muss, um korrekt mit Ihren spezifischen Daten und Anforderungen zu arbeiten. Insbesondere sollen Sie den Umgang mit negativen \(y\)-Werten, die Skalierung der SVG-viewBox entsprechend der tatsächlichen Daten und die korrekte Zuweisung des Pfades an das <mpath>-Element beachten.
Avatar von 4,6 k

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community