反映在3D空间的传染媒介

时间:2016-01-26 02:20:37

标签: algorithm geometry processing computational-geometry

当与网格相交时,应反映矢量。应用以下公式反映矢量时,结果将被设置。我在Processing中使用toxiclibs。 Here the points is before the reflection.

Here after the reflection

// Don't forget your global variables up top.
// Search through the page elements. Paragraphs are top-level, which is why I start with those.
if( type == DocumentApp.ElementType.PARAGRAPH ){

  // Look for child elements within the paragraph. Inline Drawings are children.
  if(element.asParagraph().getNumChildren() !=0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_DRAWING) {

    // For whatever reason, drawings don't have their own methods in the InlineDrawing class. This bit copies and adds it to the bottom of the doc.
    var drawing = element.asParagraph().copy();
    body.appendParagraph(drawing);
  }
}

编辑:当考虑通过减去与交叉点的交点之前的最后一个点来创建方向向量时,仍然反射关闭。 Reflection after taking into account the normalized direction.

  // Get the normal of the face that is intersected.
  ReadonlyVec3D n = isect.normal;
  // calculate the reflected vector b
  // a is the green point in the screenshot
  b = a.sub(n.scale(2 * a.dot(n)));
  b = b.add(b.getNormalized());

2 个答案:

答案 0 :(得分:1)

我有问题a while back并找到了一些有用的资源:

这是我之后使用的片段:

import toxi.geom.Vec3D;

Vec3D[] face = new Vec3D[3];
float ai = TWO_PI/3;//angle increment
float r  = 300;//overall radius
float ro = 150;//random offset

Vec3D n;//normal
Ray r1;

void setup() {
  size(500, 500, P3D);
  for (int i = 0 ; i < 3; i++) face[i] = new Vec3D(cos(ai * i) * r + random(ro), random(-50, 50), sin(ai * i) * r + random(ro));
  r1 = new Ray(new Vec3D(-100, -200, -300), new Vec3D(100, 200, 300));
}
void draw() {
  background(255);
  lights();
  translate(width/2, height/2, -500);
  rotateX(map(mouseY, 0, height, -PI, PI));
  rotateY(map(mouseX, 0, width, -PI, PI));
  //draw plane
  beginShape(TRIANGLES);
  for (Vec3D p : face) vertex(p.x, p.y, p.z);
  endShape();
  //normals
  Vec3D c = new Vec3D();//centroid
  for (Vec3D p : face) c.addSelf(p);
  c.scaleSelf(1.0/3.0);
  Vec3D cb = face[2].sub(face[1]);
  Vec3D ab = face[0].sub(face[1]);
  n = cb.cross(ab);//compute normal
  n.normalize();
  line(c.x, c.y, c.z, n.x, n.y, n.z);//draw normal

  pushStyle();
  //http://paulbourke.net/geometry/planeline/
  //line to plane intersection u = N dot ( P3 - P1 ) / N dot (P2 - P1), P = P1 + u (P2-P1), where P1,P2 are on the line and P3 is a point on the plane
  Vec3D P2SubP1 = r1.end.sub(r1.start);
  Vec3D P3SubP1 = face[0].sub(r1.start);
  float u = n.dot(P3SubP1) / n.dot(P2SubP1);
  Vec3D P = r1.start.add(P2SubP1.scaleSelf(u));
  strokeWeight(5);
  point(P.x, P.y, P.z);//point of ray-plane intersection

  //vector reflecting http://www.3dkingdoms.com/weekly/weekly.php?a=2
  //R = 2*(V dot N)*N - V
  //Vnew = -2*(V dot N)*N + V
  //PVector V = PVector.sub(r1.start,r1.end);
  Vec3D V = r1.start.sub(P);
  Vec3D R = n.scaleSelf(2 * (V.dot(n))).sub(V);
  strokeWeight(1);
  stroke(0, 192, 0);
  line(P.x, P.y, P.z, R.x, R.y, R.z);
  stroke(192, 0, 0);
  line(r1.start.x, r1.start.y, r1.start.z, P.x, P.y, P.z);
  stroke(0, 0, 192);
  line(P.x, P.y, P.z, r1.end.x, r1.end.y, r1.end.z);
  popStyle();
}
void keyPressed() {   
  setup();
}//reset
class Ray {
  Vec3D start = new Vec3D(), end = new Vec3D();
  Ray(Vec3D s, Vec3D e) {   
    start = s ; 
    end = e;
  }
}

请注意,这是概念的基本证明。 Toxiclibs可能已经提供了Ray / Face类。

Ray Reflection Processing preview

答案 1 :(得分:0)

假设你有事件方向id和交叉点n的法线,那么反射rd

rd = 2 * dot(n,id) * n - id

其中所有向量都被归一化。

在您的情况下,如果b是绿点,isect是交点,那么id = b - isect会进行标准化。

因此反射光线r(假设它有原点和方向)是

r.direction = rd
r.origin = isect

您还可以查看此Wikipedia文章。 https://en.wikipedia.org/wiki/Specular_reflection