2

I'm working with JavaScript(React) on a geometry program that creates the axonometry(better parallel projections) of the specified object defined by vertices and faces(a face can have different numbers of vertices).

enter image description here

It works perfectly when you do not need faces to be opaque otherwise there are faces above other that should be below.

So I want to order my list of faces from the further to the nearest:

[
[[100, 0, 100], [50, 50, 50], [120, 170, 120], [10, 200, 150]],
[[10, 20, 30], [10, 200, 250], [50, 50, 50], [100, 30, 30]],...
]

I will use faces.sort(sortingFunction).

I don't care about intersecting faces

(it will take the faces of all objects together)

How should sortingFunction be?

You have to consider how is the axonometry defined. It is defined by the X-, Y-axis rotation(Xrotation can be both greater and smaller than Yrotation), Z rotation is π / 4 (90°).

Here is an old version of the application that makes you understand what I mean: http://dev_proiezioni.surge.sh/

Sorry for my terrible English. Thanks

Ahmet Emre Kilinc
  • 5,489
  • 12
  • 30
  • 42
HomoVafer
  • 301
  • 2
  • 12

4 Answers4

2

What you are trying to do is called "back-face culling. One common technique is to determine if the list of the points in the representation of a polygon are in clockwise or counterclockwise order from the point of view of the camera. This requires that you are very careful about how you create the list of vertices. For more details, check out the wikipedia article: https://en.wikipedia.org/wiki/Back-face_culling. The Implementation section describes the mathematics involved which you will have to translate into JavaScript. Note that this technique is faster than sorting the list of faces because it requires checking each face only once rather than comparing each face against other faces.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
1

I don't care about intersecting faces

That means that we can reduce the plains to points, by taking the point in the middle:

const vecOp = op => (a, b) => a.map((c, i) => op(c,  b[i] || b));

const add = vecOp((a, b) => a + b);
const sub = vecOp((a, b) => a - b);
const mul = vecOp((a, b) => a * b);
const div = vecOp((a, b) => a / b);
 const sum = v => v.reduce((a, b) => a + b, 0);

const middle = (a, b) =>  div(add(a, b), 2);

 const planeToPoint = ([a, b, c, d]) => middle(
   middle(a, b),
   middle(c, d)
 );

Now to sort by "closer to camera", one could draw a line between the centers of two planes, which will result in a direction:

 const aToB = (a, b) => 
   sub(
    planeToPoint(b),
    planeToPoint(a)
  );

Now we could turn the camera rotation into a camera lookAt vector :

 const rotToVec = (yaw, pitch) => ([
   Math.cos(yaw) * Math.cos(pitch),
   Math.sin(yaw) * Math.cos(pitch),
   Math.sin(pitch)
 ]);

and that direction can be compared to the cameras direction resulting in an angle between them:

 const angle = (a, b) => sum(mul(a, b)) / sum(a) * sum(b)

Now lets turn that alltogether:

 const camVec = rotToVec(cam.yaw, cam.pitch);

 planes.sort((a, b) =>
  Math.abs(angle(aToB(a, b), camVec)) < Math.PI / 4 /*90°*/ ? 1 : -1
 );

Disclaimer: I neither tried the code above, nor did I work with parallel projections, nor am I good at math, so take my words with caution, I have no idea what I'm talking about

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
1

For an approximate solution, use a 3D to 3D transform, and consider the Z coordinate. For every face, keep the nearest Z and sort the faces on this Z.

For a more exact solution, consider https://en.wikipedia.org/wiki/Newell%27s_algorithm.

0

Sort by the distance from where you camera is.

function distanceBetweenTwoPoints (p1, p2) {
  return Math.hypot(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z)
}

function sortFunction (p1, p2) {
  return distanceBetweenTwoPoints(camera, p1) > distanceBetweenTwoPoints(camera,p2) ? -1 : 1
}

Tweak the sign > depending on which order you'd like.

Lazar Ljubenović
  • 18,976
  • 10
  • 56
  • 91
  • Thanks, but how can I find camera position in a parallel projection? And how should I approximate a face to a point? The median one? – HomoVafer Oct 02 '18 at 16:02
  • Ah, indeed. Didn't think through, sorry. I think you'll have more luck with answers on some Math-related Stack Exchange site. – Lazar Ljubenović Oct 02 '18 at 16:05