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 disk 015 in the xy-plane centered at the origin. 016<p> 017 See <a href="https://en.wikipedia.org/wiki/Disk_(mathematics)" target="_top"> 018 https://en.wikipedia.org/wiki/Disk_(mathematics)</a> 019 020 @see DiskSector 021*/ 022public class Disk extends Model implements MeshMaker 023{ 024 public final double r; 025 public final int n; 026 public final int k; 027 028 /** 029 Create a disk in the xy-plane with radius 1, 030 with 12 spokes coming out of the center, and 031 with 6 concentric circles around the disk. 032 */ 033 public Disk( ) 034 { 035 this(1, 6, 12); 036 } 037 038 039 /** 040 Create a disk in the xy-plane with radius 041 {@code r}, with 12 spokes coming out of the 042 center, and with 6 concentric circles around 043 the disk. 044 045 @param r radius of the disk 046 */ 047 public Disk(final double r) 048 { 049 this(r, 6, 12); 050 } 051 052 053 /** 054 Create a disk in the xy-plane with radius 055 {@code r}, with {@code k} spokes coming out 056 of the center, and with {@code n} concentric 057 circles around the disk. 058 <p> 059 If there are {@code k} spokes, then each circle around 060 the center will have {@code k} line segments. 061 If there are {@code n} concentric circles around the 062 center, then each spoke will have {@code n} line segments. 063 <p> 064 There must be at least three spokes and at least 065 one concentric circle. 066 067 @param r radius of the disk 068 @param n number of concentric circles 069 @param k number of spokes in the disk 070 @throws IllegalArgumentException if {@code n} is less than 1 071 @throws IllegalArgumentException if {@code k} is less than 3 072 */ 073 public Disk(final double r, int n, int k) 074 { 075 super(String.format("Disk(%.2f,%d,%d)", r, n, k)); 076 077 if (n < 1) 078 throw new IllegalArgumentException("n must be greater than 0"); 079 if (k < 3) 080 throw new IllegalArgumentException("k must be greater than 2"); 081 082 this.r = r; 083 this.n = n; 084 this.k = k; 085 086 // Create the disk's geometry. 087 088 final double deltaR = r / n, 089 deltaTheta = 2 * Math.PI / k; 090 091 // An array of vertices to be used to create line segments. 092 final Vertex[][] v = new Vertex[n][k]; 093 094 // Create all the vertices. 095 for (int j = 0; j < k; ++j) // choose a spoke (an angle) 096 { 097 final double c = Math.cos(j * deltaTheta), 098 s = Math.sin(j * deltaTheta); 099 for (int i = 0; i < n; ++i) // move along the spoke 100 { 101 final double ri = (i + 1) * deltaR; 102 v[i][j] = new Vertex( ri * c, 103 ri * s, 104 0 ); 105 } 106 } 107 final Vertex center = new Vertex(0,0,0); 108 109 // Add all of the vertices to this model. 110 for (int i = 0; i < n; ++i) 111 { 112 for (int j = 0; j < k; ++j) 113 { 114 addVertex( v[i][j] ); 115 } 116 } 117 addVertex( center ); 118 final int centerIndex = n * k; 119 120 // Create the spokes connecting the center to the outer circle. 121 for (int j = 0; j < k; ++j) // choose a spoke 122 { // v[0][j] 123 addPrimitive(new LineSegment( centerIndex, (0 * k) + j )); 124 for (int i = 0; i < n - 1; ++i) 125 { // v[i][j] v[i+1][j] 126 addPrimitive(new LineSegment( (i * k) + j, ((i+1) * k) + j )); 127 } 128 } 129 130 // Create the line segments around each concentric circle. 131 for (int i = 0; i < n; ++i) // choose a circle 132 { 133 for (int j = 0; j < k - 1; ++j) 134 { // v[i][j] v[i][j+1] 135 addPrimitive(new LineSegment( (i * k) + j, (i * k) + (j + 1) )); 136 } 137 // close the circle 138 addPrimitive(new LineSegment( (i * k) + (k-1), (i * k) + 0 )); 139 } // v[i][k-1] v[i][0] 140 } 141 142 143 144 // Implement the MeshMaker interface (three methods). 145 @Override public int getHorzCount() {return n;} 146 147 @Override public int getVertCount() {return k;} 148 149 @Override 150 public Disk remake(final int n, final int k) 151 { 152 return new Disk(this.r, n, k); 153 } 154}//Disk