diff --git a/src/main/java/fr/univamu/App.java b/src/main/java/fr/univamu/App.java
index 37538ea0b1d2d08168b10ba31f4851ae45fc5aca..cdb1e61289fa92a4237098886c6c8dc02207fe1d 100644
--- a/src/main/java/fr/univamu/App.java
+++ b/src/main/java/fr/univamu/App.java
@@ -1,12 +1,10 @@
 package fr.univamu;
 
-import fr.univamu.geo.Disc;
-import fr.univamu.geo.Shape;
-import fr.univamu.geo.Star;
-import fr.univamu.geo.Vector2D;
+import fr.univamu.geo.*;
 import fr.univamu.svg.SvgElement;
 
 import java.io.FileNotFoundException;
+import java.util.List;
 
 import static fr.univamu.svg.SvgAttribute.tag;
 
@@ -29,6 +27,14 @@ public class App {
   }
 
   public static void main(String[] args) throws FileNotFoundException {
-     write(new Star(7,3),"out/star.svg");
+    Shape shape1 = new Star(7, 3)
+        .scale(3, 2)
+        .rotate(Math.PI / 2)
+        .translate(new Vector2D(5, -5))
+        .rotate(Math.PI/4, new Vector2D(5,-5));
+    Shape circle = new Disc(3, new Vector2D(-3,1));
+    Group group1 = new Group(List.of(shape1, circle));
+    Shape group2 = group1.rotate(Math.PI/6);
+    write(new Group(List.of(group1,group2)),"out/group.svg");
   }
 }
diff --git a/src/main/java/fr/univamu/geo/Composition.java b/src/main/java/fr/univamu/geo/Composition.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa4f2611e1f597ffdc9d015ed48980fcb66dd0da
--- /dev/null
+++ b/src/main/java/fr/univamu/geo/Composition.java
@@ -0,0 +1,14 @@
+package fr.univamu.geo;
+
+import java.util.List;
+
+public record Composition(List<Transformation> transforms) implements Transformation {
+  @Override
+  public String toTag() {
+    StringBuilder builder = new StringBuilder();
+    for (Transformation transformation : transforms) {
+      builder.append(transformation.toTag()).append(" ");
+    }
+    return builder.toString();
+  }
+}
diff --git a/src/main/java/fr/univamu/geo/Disc.java b/src/main/java/fr/univamu/geo/Disc.java
index 106b5dba517f4d14a23af7753d062e7f6fbafcea..d2b7f41f83329ecf9651c0f2cf9ef904d75d13fc 100644
--- a/src/main/java/fr/univamu/geo/Disc.java
+++ b/src/main/java/fr/univamu/geo/Disc.java
@@ -13,4 +13,5 @@ public record Disc(double radius, Vector2D center) implements Shape {
         .add(tag("cx", center.x()))
         .add(tag("cy", center.y()));
   }
+
 }
diff --git a/src/main/java/fr/univamu/geo/Group.java b/src/main/java/fr/univamu/geo/Group.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f558668c54ab5b27325eb262a4b6599a4b94b5f
--- /dev/null
+++ b/src/main/java/fr/univamu/geo/Group.java
@@ -0,0 +1,18 @@
+package fr.univamu.geo;
+
+import fr.univamu.svg.SvgElement;
+
+import java.util.List;
+
+public record Group(List<Shape> shapes) implements Shape {
+
+  @Override
+  public SvgElement toSvg() {
+    SvgElement group = new SvgElement("g");
+    for (Shape shape : shapes) {
+      group.add(shape.toSvg());
+    }
+    return group;
+  }
+
+}
diff --git a/src/main/java/fr/univamu/geo/Rotation.java b/src/main/java/fr/univamu/geo/Rotation.java
new file mode 100644
index 0000000000000000000000000000000000000000..24bc15d77efb5340cc3918548e6cf5faac125a07
--- /dev/null
+++ b/src/main/java/fr/univamu/geo/Rotation.java
@@ -0,0 +1,10 @@
+package fr.univamu.geo;
+
+public record Rotation(double angle) implements Transformation {
+
+
+  @Override
+  public String toTag() {
+    return "rotate(" + angle * 180 / Math.PI + ")";
+  }
+}
diff --git a/src/main/java/fr/univamu/geo/Scale.java b/src/main/java/fr/univamu/geo/Scale.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b42048d6eb37b78ee5ba8ee3e945b17c8aed56c
--- /dev/null
+++ b/src/main/java/fr/univamu/geo/Scale.java
@@ -0,0 +1,8 @@
+package fr.univamu.geo;
+
+public record Scale(double xFactor, double yFactor) implements Transformation {
+  @Override
+  public String toTag() {
+    return "scale(" + xFactor + "," + yFactor + ")";
+  }
+}
diff --git a/src/main/java/fr/univamu/geo/Shape.java b/src/main/java/fr/univamu/geo/Shape.java
index 5b434a1f12aa88d58e5d262aee54b3d244385b3a..b4f5b0695cc2e5a87481bf9e296a405b70e44dcb 100644
--- a/src/main/java/fr/univamu/geo/Shape.java
+++ b/src/main/java/fr/univamu/geo/Shape.java
@@ -2,8 +2,45 @@ package fr.univamu.geo;
 
 import fr.univamu.svg.SvgElement;
 
+import java.util.List;
+
 public sealed interface Shape
-  permits Disc, Polygon {
+  permits Disc, Polygon, Transformed, Group {
 
   SvgElement toSvg();
+
+  default Shape transform(Transformation transform) {
+    return new Transformed(this, transform);
+  }
+
+  default Shape translate(Vector2D move) {
+    return this.transform(new Translation(move));
+  }
+
+  default Shape translate(double x, double y) {
+    return this.translate(new Vector2D(x,y));
+  }
+
+  default Shape rotate(double radian) {
+    return this.transform(new Rotation(radian));
+  }
+
+  default Shape rotate(double radian, Vector2D center) {
+    return this.transform(new Composition(
+        List.of(
+            new Translation(center),
+            new Rotation(radian),
+            new Translation(center.opposite())
+        )
+    ));
+  }
+
+  default Shape scale(double xFactor, double yFactor) {
+    return this.transform(new Scale(xFactor, yFactor));
+  }
+
+  default Shape scale(double factor) {
+    return this.scale(factor,factor);
+  }
+
 }
diff --git a/src/main/java/fr/univamu/geo/Transformation.java b/src/main/java/fr/univamu/geo/Transformation.java
new file mode 100644
index 0000000000000000000000000000000000000000..98f26c2416dcdcee9733d35105e91113955971dc
--- /dev/null
+++ b/src/main/java/fr/univamu/geo/Transformation.java
@@ -0,0 +1,7 @@
+package fr.univamu.geo;
+
+public sealed interface Transformation
+  permits Rotation, Translation, Scale, Composition {
+
+  String toTag();
+}
diff --git a/src/main/java/fr/univamu/geo/Transformed.java b/src/main/java/fr/univamu/geo/Transformed.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac8990f53b080434e4f8968c7c5268f022257dcf
--- /dev/null
+++ b/src/main/java/fr/univamu/geo/Transformed.java
@@ -0,0 +1,20 @@
+package fr.univamu.geo;
+
+import fr.univamu.svg.SvgElement;
+
+import java.util.List;
+
+import static fr.univamu.svg.SvgAttribute.tag;
+
+public record Transformed(Shape shape, Transformation transform) implements Shape {
+
+  @Override
+  public SvgElement toSvg() {
+    return shape.toSvg().add(tag("transform", transform.toTag()));
+  }
+
+  @Override
+  public Shape transform(Transformation transform) {
+    return new Transformed(shape, new Composition(List.of(transform,this.transform)));
+  }
+}
diff --git a/src/main/java/fr/univamu/geo/Translation.java b/src/main/java/fr/univamu/geo/Translation.java
new file mode 100644
index 0000000000000000000000000000000000000000..137c43fd77f1a530c08609b9c6c776ca5a42ab4e
--- /dev/null
+++ b/src/main/java/fr/univamu/geo/Translation.java
@@ -0,0 +1,8 @@
+package fr.univamu.geo;
+
+public record Translation(Vector2D move) implements Transformation {
+  @Override
+  public String toTag() {
+    return "translate(" + move.x() + "," + move.y() + ")";
+  }
+}