001/*
002 * Renderer Models. The MIT License.
003 * Copyright (c) 2022 rlkraft@pnw.edu
004 * See LICENSE for details.
005*/
006
007package renderer.models_L;
008
009import renderer.scene.*;
010import renderer.scene.primitives.*;
011import renderer.scene.util.MeshMaker;
012
013/**
014   Create a wireframe model of a circle in
015   the xy-plane centered at the origin.
016*/
017public class Circle extends Model implements MeshMaker
018{
019   public final double r;
020   public final int n;
021
022   /**
023      Create a circle in the xy-plane with radius 1 and
024      with 16 line segments around the circumference.
025   */
026   public Circle( )
027   {
028      this(1, 16);
029   }
030
031
032   /**
033      Create a circle in the xy-plane with radius {@code r}
034      and with 16 line segments around the circumference.
035
036      @param r  radius of the circle
037   */
038   public Circle(final double r)
039   {
040      this(r, 16);
041   }
042
043
044   /**
045      Create a circle in the xy-plane with radius {@code r}
046      and with {@code n} line segments around the circumference.
047
048      @param r  radius of the circle
049      @param n  number of line segments in the circle's circumference
050      @throws IllegalArgumentException if {@code n} is less than 3
051   */
052   public Circle(final double r, final int n)
053   {
054      super(String.format("Circle(%f.2,%d)", r, n));
055
056      if (n < 3)
057         throw new IllegalArgumentException("n must be greater than 2");
058
059      this.r = r;
060      this.n = n;
061
062      // Create the circle's geometry.
063      final double deltaTheta = (2.0 * Math.PI) / n;
064
065      // Create all the vertices.
066      for (int i = 0; i < n; ++i)
067      {
068         final double c = Math.cos(i * deltaTheta),
069                      s = Math.sin(i * deltaTheta);
070         addVertex( new Vertex(r * c, r * s, 0) );
071      }
072
073      // Create the line segments around the circle.
074      for (int i = 0; i < n - 1; ++i)
075      {
076         addPrimitive(new LineSegment(i, i+1));
077      }
078      addPrimitive(new LineSegment(n-1, 0));
079   }
080
081
082
083   // Implement the MeshMaker interface (three methods).
084   @Override public int getHorzCount() {return n;}
085
086   @Override public int getVertCount() {return n;}
087
088   @Override
089   public Circle remake(final int n, final int k)
090   {
091      final int newN;
092      if (n != this.n)
093         newN = n;
094      else
095         newN = k;
096
097      return new Circle(this.r, newN);
098   }
099}//Circle