octave-patch-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-patch-tracker] [patch #8951] Calculate vertexnormals for patch o


From: Markus Mützel
Subject: [Octave-patch-tracker] [patch #8951] Calculate vertexnormals for patch objects
Date: Tue, 03 May 2016 15:13:52 +0000
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0

Follow-up Comment #17, patch #8951 (project octave):

The normals for surface objects are always calculated for the constituting
rectangles. Patches can consist of many different polygons. Probably, it would
be easier to match the implementation for surfaces to that special case (as it
is right now for vertexnormals for surfaces). But I will keep that in mind.

I will write public get and set methods for num_lights in axes. Thank you for
a pointer to that. At the moment num_lights is always 0. When "light" is
implemented in Octave, its values has to increase when a light object is added
and decrease when it is deleted. Probably, that value has to be changed also
when the "Visible" property of the light object is changed. (Still to be added
to patch #8943). Maybe add_light and remove_light methods would be better in
that case?

The Newill method does not always calculate a good normal, e.g.:

faces = [1 2 3 4];
vertices = [0, 0, 0; 1, 0, 0; 1, 1, 0; 0, -1, 0];
fn(1) = (vertices(faces(1),2) - vertices(faces(end),2)) *
(vertices(faces(1),3) + vertices(faces(end),3));
fn(2) = (vertices(faces(1),3) - vertices(faces(end),3)) *
(vertices(faces(1),1) + vertices(faces(end),1));
fn(3) = (vertices(faces(1),1) - vertices(faces(end),1)) *
(vertices(faces(1),2) + vertices(faces(end),2));
for i1 = 2:length(faces)
fn(1) = fn(1) + (vertices(faces(i1),2) - vertices(faces(i1-1),2)) *
(vertices(faces(i1),3) + vertices(faces(i1-1),3));
fn(2) = fn(2) + (vertices(faces(i1),3) - vertices(faces(i1-1),3)) *
(vertices(faces(i1),1) + vertices(faces(i1-1),1));
fn(3) = fn(3) + (vertices(faces(i1),1) - vertices(faces(i1-1),1)) *
(vertices(faces(i1),2) + vertices(faces(i1-1),2));
end
fn

fn =

     0     0     0


The normal at any one corner is [0 0 1] (or [0 0 -1]).

Or a more obfuscated example (above vertices rotated around axis [1 0 1] by
0.3rad):

vertices = [         0         0         0
    0.9777   -0.2090    0.0223
    1.1866    0.7464   -0.1866
   -0.2090   -0.9553    0.2090 ];

fn(1) = (vertices(faces(1),2) - vertices(faces(end),2)) *
(vertices(faces(1),3) + vertices(faces(end),3));
fn(2) = (vertices(faces(1),3) - vertices(faces(end),3)) *
(vertices(faces(1),1) + vertices(faces(end),1));
fn(3) = (vertices(faces(1),1) - vertices(faces(end),1)) *
(vertices(faces(1),2) + vertices(faces(end),2));
for i1 = 2:length(faces)
fn(1) = fn(1) + (vertices(faces(i1),2) - vertices(faces(i1-1),2)) *
(vertices(faces(i1),3) + vertices(faces(i1-1),3));
fn(2) = fn(2) + (vertices(faces(i1),3) - vertices(faces(i1-1),3)) *
(vertices(faces(i1),1) + vertices(faces(i1-1),1));
fn(3) = fn(3) + (vertices(faces(i1),1) - vertices(faces(i1-1),1)) *
(vertices(faces(i1),2) + vertices(faces(i1-1),2));
end

>> fn/norm(fn)
ans =
   -0.3940    0.4223   -0.8163
>> cross (vertices(end,:) - vertices(1,:), vertices(2,:) - vertices(1,:))
ans =
    0.0224    0.2090    0.9777


Due to numerical effects (double precission), the normal calculated by the
Newill method (fn) is quite different from the normals calculated at any
corner: +/- [0.0224, 0.2090, 0.9777].

I did not yet time svd nor the Newill method. But it might be an idea to check
the length of the normal that results from the Newill method and decide on
that whether we want to calculate the normal at one corner of the polygon
instead.

However, we might have to find the non-planar polygons anyway to specially
handle them in glrender.cc (bug #47677). So I had the vague idea to store that
information somehow in the graphics object to re-use it later. If we need to
calculate the svd anyway (do we?), I figured it would not matter when it would
be calculated and fall back to the faster cross-product (instead of the Newill
method) in the cases where possible.

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/patch/?8951>

_______________________________________________
  Nachricht gesendet von/durch Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]