From 1b811cd8ff6189aea84e6cf17a434fca5e4110c6 Mon Sep 17 00:00:00 2001
From: "guyslain.naves" <guyslain.naves@lis-lab.fr>
Date: Mon, 24 Oct 2022 09:37:46 +0200
Subject: [PATCH] =?UTF-8?q?T=C3=A2ches=203=20et=204?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/fr/univamu/App.java             | 16 +++++---
 src/main/java/fr/univamu/geo/Composition.java | 14 +++++++
 src/main/java/fr/univamu/geo/Disc.java        |  1 +
 src/main/java/fr/univamu/geo/Group.java       | 18 +++++++++
 src/main/java/fr/univamu/geo/Rotation.java    | 10 +++++
 src/main/java/fr/univamu/geo/Scale.java       |  8 ++++
 src/main/java/fr/univamu/geo/Shape.java       | 39 ++++++++++++++++++-
 .../java/fr/univamu/geo/Transformation.java   |  7 ++++
 src/main/java/fr/univamu/geo/Transformed.java | 20 ++++++++++
 src/main/java/fr/univamu/geo/Translation.java |  8 ++++
 10 files changed, 135 insertions(+), 6 deletions(-)
 create mode 100644 src/main/java/fr/univamu/geo/Composition.java
 create mode 100644 src/main/java/fr/univamu/geo/Group.java
 create mode 100644 src/main/java/fr/univamu/geo/Rotation.java
 create mode 100644 src/main/java/fr/univamu/geo/Scale.java
 create mode 100644 src/main/java/fr/univamu/geo/Transformation.java
 create mode 100644 src/main/java/fr/univamu/geo/Transformed.java
 create mode 100644 src/main/java/fr/univamu/geo/Translation.java

diff --git a/src/main/java/fr/univamu/App.java b/src/main/java/fr/univamu/App.java
index 37538ea..cdb1e61 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 0000000..aa4f261
--- /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 106b5db..d2b7f41 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 0000000..0f55866
--- /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 0000000..24bc15d
--- /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 0000000..8b42048
--- /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 5b434a1..b4f5b06 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 0000000..98f26c2
--- /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 0000000..ac8990f
--- /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 0000000..137c43f
--- /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() + ")";
+  }
+}
-- 
GitLab