source: trunk/gui/vizservers/nanovis/ConvexPolygon.cpp @ 380

Last change on this file since 380 was 226, checked in by mmc, 19 years ago
  • Added code for Wei's visualization server.
  • Fixed the energyLevels widget so that it doesn't barf when the user attempts to download its contents.
File size: 5.4 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 * ConvexPolygon.cpp: convex polygon class
4 *
5 * ======================================================================
6 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
7 *           Purdue Rendering and Perceptualization Lab (PURPL)
8 *
9 *  Copyright (c) 2004-2006  Purdue Research Foundation
10 *
11 *  See the file "license.terms" for information on usage and
12 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * ======================================================================
14 */
15#include "ConvexPolygon.h"
16#include <GL/glut.h>
17#include <assert.h>
18
19ConvexPolygon::ConvexPolygon(){}
20
21ConvexPolygon::ConvexPolygon(VertexVector vertices){
22    this->vertices.insert(this->vertices.begin(),
23                                vertices.begin(),
24                                vertices.end());
25}
26
27void ConvexPolygon::append_vertex(Vector4 vert){
28    vertices.push_back(vert);
29}
30
31void ConvexPolygon::insert_vertex(unsigned int index, Vector4 vert) {
32        assert(index<vertices.size());
33        vertices.insert(vertices.begin() + index, vert);
34}
35
36bool is_retained(Vector4 point, Vector4 plane){
37        return ( point * plane>=0 ) ; 
38}
39
40// Finds the intersection of the line through
41// p1 and p2 with the given plane, putting the
42// result in intersect.
43//
44// If the line lies in the plane, an arbitrary
45// point on the line is returned.
46//
47// http://astronomy.swin.edu.au/pbourke/geometry/planeline/
48bool findIntersection(Vector4 p1, Vector4 p2, Vector4 plane, Vector4 &ret){
49        float a = plane.x;
50        float b = plane.y;
51        float c = plane.z;
52        float d = plane.w;
53
54        p1.perspective_devide();
55    float x1 = p1.x;
56    float y1 = p1.y;
57    float z1 = p1.z;
58
59        p2.perspective_devide();
60    float x2 = p2.x;
61    float y2 = p2.y;
62    float z2 = p2.z;
63
64    float uDenom = a * (x1 - x2) + b * (y1 - y2) + c * (z1 - z2);
65    float uNumer = a * x1 + b * y1 + c * z1 + d;
66
67    if (uDenom == 0){
68                //plane parallel to line
69                fprintf(stderr, "Unexpected code path: ConvexPolygon.cpp\n");
70                if (uNumer == 0){
71                        for (int i = 0; i < 4; i++)
72                                ret < p1;
73                                return true;
74                }
75                return false;
76    }
77
78    float u = uNumer / uDenom;
79    ret.x = x1 + u * (x2 - x1);
80    ret.y = y1 + u * (y2 - y1);
81    ret.z = z1 + u * (z2 - z1);
82    ret.w = 1;
83        return true;
84}
85
86void ConvexPolygon::transform(Mat4x4 mat){
87        VertexVector tmp = vertices;
88        vertices.clear();
89
90        for (unsigned int i = 0; i < tmp.size(); i++) {
91                Vector4 vec = tmp[i];
92                vertices.push_back(mat.transform(vec));
93    }
94}
95
96
97void ConvexPolygon::translate(Vector4 shift){
98        VertexVector tmp = vertices;
99        vertices.clear();
100
101        for (unsigned int i = 0; i < tmp.size(); i++) {
102                Vector4 vec = tmp[i];
103                vertices.push_back(vec+shift);
104    }
105}
106
107void ConvexPolygon::clip(Plane &clipPlane) {
108        if (vertices.size() == 0) {
109                //fprintf(stderr, "ConvexPolygon: polygon has no vertices\n"); 
110                return;
111        }
112   
113    VertexVector clippedVerts;
114    clippedVerts.reserve(2 * vertices.size());
115
116    // The algorithm is as follows: for each vertex
117    // in the current poly, check to see which
118    // half space it is in: clipped or retained.
119    // If the previous vertex was in the other
120    // half space, find the intersect of that edge
121    // with the clip plane and add that intersect
122    // point to the new list of vertices.  If the
123    // current vertex is in the retained half-space,
124    // add it to the new list as well.
125
126    Vector4 intersect;
127    Vector4 plane = clipPlane.get_coeffs();
128
129    bool prevRetained = is_retained(vertices[0], plane);
130    if (prevRetained)
131                clippedVerts.push_back(vertices[0]);
132
133    for (unsigned int i = 1; i < vertices.size(); i++) {
134                bool retained = is_retained(vertices[i], plane);
135                if (retained != prevRetained) {
136                        bool found = findIntersection(vertices[i - 1], vertices[i],
137                                          plane, intersect);
138                        if (!found)
139                                assert(false);
140                        clippedVerts.push_back(intersect);
141                }
142                if (retained) {
143                        clippedVerts.push_back(vertices[i]);
144                }
145                prevRetained = retained;
146    }
147
148    bool retained = is_retained(vertices[0], plane);
149    if (retained != prevRetained) {
150                bool found = findIntersection(vertices[vertices.size() - 1], vertices[0],
151                                      plane, intersect);
152                if (!found)
153                        assert(false);
154                clippedVerts.push_back(intersect);
155    }
156
157    vertices.clear();
158    vertices.insert(vertices.begin(),
159                    clippedVerts.begin(),
160                    clippedVerts.end());
161}
162
163void ConvexPolygon::copy_vertices_to_texcoords(){
164    if(texcoords.size()>0)
165      texcoords.clear();
166
167    for (unsigned int i=0; i<vertices.size(); i++) {
168        texcoords.push_back(vertices[i]);
169    }
170}
171
172
173void ConvexPolygon::Emit(bool use_texture)
174{
175        if (vertices.size() >= 3)
176        {
177                for (unsigned int i = 0; i<vertices.size(); i++)
178                {
179                        if(use_texture){
180                                glTexCoord4fv((float *)&(texcoords[i]));
181                                //glTexCoord4fv((float *)&(vertices[i]));
182                        }
183                        glVertex4fv((float *)&(vertices[i]));
184                }
185         }
186}
187
188
189void ConvexPolygon::Emit(bool use_texture, Vector3& shift, Vector3& scale)
190{
191        if (vertices.size() >= 3)
192        {
193                for (unsigned int i = 0; i<vertices.size(); i++)
194                {
195                        if(use_texture)
196                                glTexCoord4fv((float *)&(vertices[i]));
197
198                        Vector4 tmp = (vertices[i]);
199                        Vector4 shift_4d = Vector4(shift.x, shift.y, shift.z, 0);
200                        tmp = tmp + shift_4d;
201                        tmp.x = tmp.x * scale.x;
202                        tmp.y = tmp.y * scale.y;
203                        tmp.z = tmp.z * scale.z;
204                        glVertex4fv((float *)(&tmp));
205                }
206         }
207}
Note: See TracBrowser for help on using the repository browser.