--- polygon Define a planar (2D) shape with more than three sides Parameters, associated elements and modifiers must be within braces. polygon {...} The polygon definition is assignable to a scene language ID. #declare ID00 = polygon {...} #local ID00 = polygon {...} ID may be referenced within blocks: polygon{} and object{}. Description: ------------ The polygon object is useful for creating rectangles, squares and other planar shapes with more than three edges. The syntax is: polygon { Number_Of_Points, ... } The Number_Of_Points count tells how many points are used to define the 'polygon object'. The points through describe one or more sub-polygons. A 'polygon object' can contain any number of sub-polygons, either overlapping or not. Where evaluation points are inside an odd number of sub-polygons, they are considered to be part of the planar 'polygon object'. Where evaluation points are inside an even number of sub-polygons or outside all sub-polygons, they are considered to be outside the planar 'polygon object'. When you repeat the first point of a sub-polygon, it closes it and starts a new sub-polygon's point sequence. The points of each sub-polygon define an enclosed region in the 2D x-y plane. All points of a polygon whether specified as 2D or 3D vectors are initially interpreted as three-dimensional vectors internally. If specifying full 3D vectors, the z offset of the x-y plane may be specified, but the z vector component values must all be the same; They must lay on the same plane. If this is not the case, an error occurs. It is common to use two-dimensional vectors to describe the polygon. POV-Ray assumes that the z value is zero in this case. The clock-wise or counter-clockwise order of points in the 2D x,y plane does not matter to the inside sub-polygon tests. Such in / out of sub-polygon tests affect aspects of the polygon shape's potential pattern implementation and whether intersections are found. The clock-wise or counter-clockwise order of points for the first loop specified in the 2D x,y plane does affect the returned normal vector! If the order of vertices is given in a clock-wise way such as: #declare PgonCW = polygon { 5, <0, 0> <0, 1>, <1, 1> <1, 0>, <0, 0> } The raw surface normal is always -z. If the order of vertices is given in a counter-clockwise way such as: #declare PgonCCW = polygon { 5, <0, 0> <1, 0>, <1, 1> <0, 1>, <0, 0> } The raw surface normal is always +z. // Sample scene. 'yuqk polygon.pov +w800 +h800 +p +mv3.8' global_settings { assumed_gamma 1.0 } #declare VarOrthoMult = 3.0/max(image_width/image_height,image_height/image_width); #declare Camera01z = camera { orthographic location <0,0,-2> direction z right VarOrthoMult*x*max(1,image_width/image_height) up VarOrthoMult*y*max(1,image_height/image_width) } #declare PgonCW = polygon { // Normal set to -z 10, <-1.0, -1.0>, <-1.0, +1.0>, <+1.0, +1.0>, <+1.0, -1.0>, <-1.0, -1.0>, <-0.6, -0.6>, <-0.6, +0.6>, <+0.6, +0.6>, <+0.6, -0.6>, <-0.6, -0.6>, } #declare PgonCCW = polygon { // Normal set to +z 10, <-1.0, -1.0>, <+1.0, -1.0>, <+1.0, +1.0>, <-1.0, +1.0>, <-1.0, -1.0>, <-0.6, -0.6>, <+0.6, -0.6>, <+0.6, +0.6>, <-0.6, +0.6>, <-0.6, -0.6>, } #declare TxtrE = texture { finish { emission <0,1,0> } } #declare TxtrI = texture { finish { emission <1,0,0> } } polygon { PgonCW texture { TxtrE } interior_texture { TxtrI } } camera { Camera01z } Issues: ------- If the last sub-polygon is not closed a warning is issued and the program automatically repeats the first point to complete the current sub-polygon. The warning and automatic closing are only reliable where there is a single sub-polygon in the 'polygon object'. Where more than one sub-polygon is expected the code involved is not reliable and results may be unstable. In recent official releases of POV-Ray, the majority of the parse time checking results in invalid polygons which are simply ignored without any parser warnings or errors. The yuqk fork has been updated to mostly issue parse time errors on problems. Excepting when closing an unclosed polygon vertices list as outlined in the previous paragraph. Not all possible issues with vertices lists are flagged by yuqk's parser updates or results in polygon's being marked invalid and ignored in our official POV-Ray releases. Whether some of these more obscure issues are worth testing for is a question. Mostly, they'll result in artefacts which might or might not matter to any usage. TODO. Due the state of the parser for the polygon object, the potential value pattern support for the polygon object currently does not support the per segment offset and tapering features. Or, arbitrary point to point connections based upon the points defined. Activating these features of the potential code will require the implementation of a 'laxparsing' boolean keyword for the polygon object itself - so more flexible point lists can reach the potential pattern code. The yuqk fork state: -------------------- 'polygon' was modified. Where useable: -------------- Only within Scene Description Language (SDL) during parsing. Shape Potential Pattern Support: -------------------------------- The polygon object can be used as the object in a potential{} value pattern. potential { Polygon00 ip_type // Types 0..6 supported. ip_offset // Size / thickness of negative / inside // potential values returned. ip_mode // Modes 0..5 supported. ip_threshold // Currently unused by the polygon potential // value pattern code. } More on each potential pattern keyword supported by the polygon object. ip_type 0 - An (x,y) or (u,v), 2D inside test which is infinite in z. A value of 1.0 is returned if the evaluation point is inside the polygon object and 0.0 otherwise. The ip_mode setting is ignored with this type, but the return value is multiplied by the ip_offset value (so an ip_offset > 0.0 must be specified). In being able to return various inside true values the thinking is complex patterns can be built up by adding together function wraps of the polygon's potential pattern. Note. The 'inverse' keyword flips the 0 and 1 return values when this type is used. 1 - Return bounding box frame values using min / max extent corners 2 - Return spherical values marking the bounding box's center. 3 - An option similar to (1), but the bounding box frame is 'heavier' in adding mid point connections. 4 - Create spherical regions at each point specified by the polygon object. 5 - Create values connecting all points specified by the polygon object. 6 - Extends (5) by also calculating a z value about z==0 which fills in the sub-polygon regions testing as inside the 'polygon object'. This potential type create values that can be used to create a 3D, isosurface representation of a polygon object. ip_mode While always accounting for the ip_offset value, the ip_mode sets the kind of return value treatment to use. 0 - Return the distance to the center, points, point to point connections or full 3D representation. 1 - Like (0), but returns the square of the distance. (This avoids a sqrt() call, but its values are generally less useful / intuitive to use downstream. 2 - Return 't' value along the total connect path (connection + t) Where there is no clear meaning for 't' value along some point to point connection it's usually defaulted to 0, making this return option and 3 alike in such cases. 3 - Return the point to point connection number. The meaning here is somewhat contrived where the value field returned isn't strictly based upon the polygon object's point list. 4 - Return 't' value for the closest point to point connection. As with (3) the meaning of 't' sometimes either contrived or hard set to 0. 5 - Returns -1.0 if the value calculated with option (0) is <0.0 or it returns +1.0 otherwise. ip_offset - A value > 0.0 which usually defines the 'depth' of the negative value region - the radius of spheres or the wire like connections between points. When used with ip_type 0 the value is a multiplier for the 0 or 1 inside test value returned. Note. One of the thoughts in adding extensive potential{} support to the polygon object is that it provides a path to define arbitrarily drawn tiling patterns. Drawn patterns which should be immune to most (all?) of the numerical noise issues we see with the tiling scalar value pattern implementation. Example code: ------------- // Sample scene. 'yuqk polygonPotentialMath.pov +w800 +h800 +p +mv3.8' global_settings { assumed_gamma 1.0 } #declare VarOrthoMult = 3.5/max(image_width/image_height,image_height/image_width); #declare Camera01z = camera { orthographic location <0,0,-2> direction z right VarOrthoMult*x*max(1,image_width/image_height) up VarOrthoMult*y*max(1,image_height/image_width) } #declare PgonCW = polygon { // Normal set to -z 10, <-1.0, -1.0>, <-1.0, +1.0>, <+1.0, +1.0>, <+1.0, -1.0>, <-1.0, -1.0>, <-0.6, -0.6>, <-0.6, +0.6>, <+0.6, +0.6>, <+0.6, -0.6>, <-0.6, -0.6>, } #declare PgonCCW = polygon { // Normal set to +z 10, <-1.0, -1.0>, <+1.0, -1.0>, <+1.0, +1.0>, <-1.0, +1.0>, <-1.0, -1.0>, <-0.6, -0.6>, <+0.6, -0.6>, <+0.6, +0.6>, <-0.6, +0.6>, <-0.6, -0.6>, } #declare FnA = function { pattern { // Normal irrelevant in potential pattern use potential { PgonCW ip_type 0 ip_offset 0.5 } } } #declare FnB = function { pattern { // Normal irrelevant in potential pattern use potential { PgonCCW ip_type 0 ip_offset 0.5 } rotate z*45 } } #declare FnAplusB = function { FnA(x,y,z) + FnB(x,y,z) } plane { -z 0 pigment { function { FnAplusB(x,y,z) } } finish { emission 1 } } camera { Camera01z } // If you want to see linear values in the preview display over gamma // corrected ones, add 'display_gamma=1.0' to the command line. --- // Sample scene. 'yuqk polygonPotentialType1to3.pov +w800 +h800 +p +mv3.8' global_settings { assumed_gamma 1.0 } #declare VarOrthoMult = 3.5/max(image_width/image_height,image_height/image_width); #declare Camera01z = camera { orthographic location <0,0,-2> direction z right VarOrthoMult*x*max(1,image_width/image_height) up VarOrthoMult*y*max(1,image_height/image_width) } #declare PgonCW = polygon { // Normal set to -z 10, <-1.0, -1.0>, <-1.0, +1.0>, <+1.0, +1.0>, <+1.0, -1.0>, <-1.0, -1.0>, <-0.6, -0.6>, <-0.6, +0.6>, <+0.6, +0.6>, <+0.6, -0.6>, <-0.6, -0.6>, } plane { -z 0 pigment { potential { PgonCW //ip_type 1 //ip_type 2 ip_type 3 ip_offset 0.02 ip_mode 0 } raw_wave color_map { [-0.1 rgb <1,0,0>] [+0.0 rgb <0,0,0>] [+0.1 rgb <0,1,0>] } } finish { emission 1 } } camera { Camera01z } // If you want to see linear values in the preview display over gamma // corrected ones, add 'display_gamma=1.0' to the command line. --- // Sample scene. 'yuqk polygonPotentialType4to6.pov +w800 +h800 +p +mv3.8' global_settings { assumed_gamma 1.0 } #declare VarOrthoMult = 3.5/max(image_width/image_height,image_height/image_width); #declare Camera01z = camera { orthographic location <0,0,-2> direction z right VarOrthoMult*x*max(1,image_width/image_height) up VarOrthoMult*y*max(1,image_height/image_width) } #declare PgonCW = polygon { // Normal set to -z 10, <-1.0, -1.0>, <-1.0, +1.0>, <+1.0, +1.0>, <+1.0, -1.0>, <-1.0, -1.0>, <-0.6, -0.6>, <-0.6, +0.6>, <+0.6, +0.6>, <+0.6, -0.6>, <-0.6, -0.6>, } plane { -z 0 pigment { potential { PgonCW //ip_type 4 //ip_type 5 ip_type 6 ip_offset 0.02 ip_mode 0 } raw_wave color_map { [-0.1 rgb <1,0,0>] [+0.0 rgb <0,0,0>] [+0.1 rgb <0,1,0>] } } finish { emission 1 } } camera { Camera01z } // If you want to see linear values in the preview display over gamma // corrected ones, add 'display_gamma=1.0' to the command line. // SPDX-License-Identifier: CC-BY-SA-4.0