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.*; 011 012/** 013 Create a wireframe model of a camera's perspective view frustum. 014 That is, create a frustum of a pyramid along the negative z-axis 015 with its apex at the origin. 016<p> 017 This class has two constructors that mimic the projPerspective() 018 methods from the {@link Camera} class. 019<p> 020 See <a href="https://en.wikipedia.org/wiki/Viewing_frustum" target="_top"> 021 https://en.wikipedia.org/wiki/Viewing_frustum</a> 022*/ 023public class ViewFrustumModel extends Model 024{ 025 /** 026 Create a frustum of a pyramid along the negative z-axis with 027 a front face at {@code z = -0.25}, a back face at {@code z = -1}, 028 and the front face bounded by {@code -0.25 <= x <= 0.25} and 029 {@code -0.25 <= y <= 0.25}. 030 */ 031 public ViewFrustumModel( ) 032 { 033 this(-0.25, 0.25, -0.25, 0.25, 0.25, 1); 034 } 035 036 037 /** 038 Create a frustum of a pyramid along the negative z-axis that 039 mimics a {@link Camera}'s perspective view volume. 040 041 @param left left edge of the front face in the plane z = -near 042 @param right right edge of the front face in the plane z = -near 043 @param bottom bottom edge of the front face in the plane z = -near 044 @param top top edge of the front face in the plane z = -near 045 @param near distance from the origin to the front face 046 @param far distance from the origin to the back face 047 */ 048 public ViewFrustumModel(final double left, final double right, 049 final double bottom, final double top, 050 final double near, final double far) 051 { 052 super("View Frustum Model"); 053 054 addVertex(new Vertex(left, top, -near), 055 new Vertex(right, top, -near), 056 new Vertex(right, bottom, -near), 057 new Vertex(left, bottom, -near), 058 new Vertex( (left/near)*far, (top/near)*far, -far), 059 new Vertex((right/near)*far, (top/near)*far, -far), 060 new Vertex((right/near)*far, (bottom/near)*far, -far), 061 new Vertex( (left/near)*far, (bottom/near)*far, -far)); 062 063 // front (near) face 064 addPrimitive(new LineSegment(0, 1), 065 new LineSegment(1, 2), 066 new LineSegment(2, 3), 067 new LineSegment(3, 0)); 068 // back (far) face 069 addPrimitive(new LineSegment(4, 5), 070 new LineSegment(5, 6), 071 new LineSegment(6, 7), 072 new LineSegment(7, 4)); 073 // lines from front to back 074 addPrimitive(new LineSegment(0, 4), 075 new LineSegment(1, 5), 076 new LineSegment(2, 6), 077 new LineSegment(3, 7)); 078 } 079 080 081 /** 082 Here, the frustum is determined by a vertical "field of view" 083 angle and an aspect ratio for the front face. 084 085 @param fovy angle in the y-direction subtended by the front face 086 @param aspect aspect ratio of the front face 087 @param near distance from the origin to the front face 088 @param far distance from the origin to the back face 089 */ 090 public ViewFrustumModel(final double fovy, final double aspect, 091 final double near, final double far) 092 { 093 // top = near * Math.tan((Math.PI/180.0)*fovy/2.0) 094 // left = -top * aspect 095 // right = top * aspect 096 // bottom = -top 097 this(-near * Math.tan((Math.PI/180.0)*fovy/2.0) * aspect, 098 near * Math.tan((Math.PI/180.0)*fovy/2.0) * aspect, 099 -near * Math.tan((Math.PI/180.0)*fovy/2.0), 100 near * Math.tan((Math.PI/180.0)*fovy/2.0), 101 near, 102 far); 103 } 104}//ViewFrustumModel