- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在寻找一种通过在 Android 上围绕 Y 轴旋转样条线来创建 3D 对象的方法。结果应该是一个类似碗/玻璃的物体:
http://www.3d-resources.com/cinema_4d_tutorials/realistic_glass_tutorial.html
表单的形状应该是动态的,用户应该能够在应用程序中调整样条线的半径和控制点。
基本上我正在寻找最直接的方法来实现这一点。有人能指出我正确的方向吗? (框架,示范性实现,...)
这种建模技术有一个众所周知的名称吗? (在 Cinema 4d 中,它被称为“车床 nurbs”)
-----编辑-----
我的输入是一系列 2D 控制点(贝塞尔曲线路径)以及旋转轴和样条线之间的半径。我的输出应该是通过绕轴旋转样条线创建的对象的实时 3D 渲染。
最佳答案
有关buzier curve的信息以及关于surface rotation .
您可以从 github 获取代码.
我几年前写的,当时我对 Java 还很陌生,所以代码质量可能有点差......
输出:
主要类(class):
贝塞尔曲线:
package kpi.ua.shapes;
import java.awt.Graphics2D;
import java.util.LinkedList;
import java.util.List;
public class BezierCurve {
private List<Point> allPoints;
public BezierCurve(List<Point> allPoints) {
this.allPoints = allPoints;
}
public Point getValue(double t) {
Point result = new Point();
int i = 0;
Double x=new Double(0);
Double y=new Double(0);
for (Point p : allPoints) {
x+=p.getX() * b(i, allPoints.size()-1, t);
y+=p.getY() * b(i, allPoints.size()-1, t);
i++;
}
result.setX(x);
result.setY(y);
return result;
}
private Double b(int i, int n, double t) {
return fact(n)* Math.pow(t, i) * Math.pow(1 - t, n - i) / (fact(i) * fact(n - i));
}
private int fact(int num) {
return (num == 0) ? 1 : num * fact(num - 1);
}
public void drawCarcass(Graphics2D gr) {
Double[] x=new Double[allPoints.size()];
Double[] y=new Double[allPoints.size()];
int i=0;
for(Point p:allPoints){
x[i]=p.getX();
y[i]=p.getY();
i++;
}
// gr.drawPolygon(x, y, i);
}
public List<Line> getCurve(){
LinkedList<Line> curve=new LinkedList<Line>();
Double t=0.0;
Point prev = getValue(t);
Point next;
while (t <= 1) {
next =getValue(t);
curve.add(new Line(prev,next));
// gr.drawLine(prev.getX(), prev.getY(), next.getX(), next.getY());
prev = next;
t += 0.001;
}
next = getValue(t);
curve.add(new Line(prev,next));
return curve;
//gr.drawLine(prev.getX(), prev.getY(), next.getX(), next.getY());
}
public void drawCurve(Graphics2D gr){
// Double t=0.0;
// Point prev = getValue(t);
// Point next;
// gr.setColor(Color.yellow);
// gr.setStroke(new BasicStroke(2.5f));
// while (t <= 1) {
// next =getValue(t);
// // gr.drawLine(prev.getX(), prev.getY(), next.getX(), next.getY());
// prev = next;
// t += 0.001;
// }
// next = getValue(t);
// gr.drawLine(prev.getX(), prev.getY(), next.getX(), next.getY());
}
}
复杂:
package kpi.ua.shapes;
public class Complex extends Point {
private Double re;
private Double im;
public Complex(Double im, Double re) {
this.im = im;
this.re = re;
Double r = Math.sqrt(im * im + re * re);
Double fi = Math.atan(im / re);
this.x=r * Math.cos(fi);
this.y=r * Math.sin(fi);
}
public Double getRe() {
return re;
}
public void setRe(Double re) {
this.re = re;
}
public Double getIm() {
return im;
}
public void setIm(Double im) {
this.im = im;
}
}
锥体:
package kpi.ua.shapes;
public class Cone {
private Double a;
private Double b;
private Double c;
private Double fi;
public Cone() {
super();
}
public Cone(Double a, Double b, Double c) {
super();
this.a = a;
this.b = b;
this.c = c;
}
public Double getA() {
return a;
}
public void setA(Double a) {
this.a = a;
}
public Double getB() {
return b;
}
public void setB(Double b) {
this.b = b;
}
public Double getC() {
return c;
}
public void setC(Double c) {
this.c = c;
}
public Double getFi() {
return fi;
}
public void setFi(Double fi) {
this.fi = fi;
}
public Point3D getPoint(Double fi,Double r){
Double x=this.a*r*Math.cos(fi);
Double y=this.b*r*Math.sin(fi);
Double z=this.c*r;
return new Point3D(x, y, z);
}
}
锥面:
package kpi.ua.shapes;
import java.awt.Graphics2D;
import java.util.LinkedList;
import java.util.List;
import kpi.ua.util.ControlUtil;
import kpi.ua.util.GraphicUtil;
public class ConeSurface {
private List<Point3D> conePoints;
public List<Point3D> getConePoints() {
return conePoints;
}
public void setConePoints(List<Point3D> conePoints) {
this.conePoints = conePoints;
}
public void calcConePoints(){
Cone cone = new Cone(ControlUtil.CONE_PARAMETR_A, ControlUtil.CONE_PARAMETR_B, ControlUtil.CONE_PARAMETR_C);
Double r = ControlUtil.CONE_START_RADIOUS;
conePoints=new LinkedList<Point3D>();
while (r >= 0) {
for (double fi = 0; fi < 2 * Math.PI; fi += ControlUtil.STEP_BY_FI) {
conePoints.add(cone.getPoint(fi, r));
conePoints.add(cone.getPoint(fi+ControlUtil.STEP_BY_FI, r));
if(r!=0){
conePoints.add(cone.getPoint(fi, r-1));
}
}
r--;
}
}
public void drawCone(Graphics2D gr){
if(conePoints==null)
calcConePoints();
GraphicUtil.drawTriangulation(gr, conePoints);
}
}
线路:
package kpi.ua.shapes;
public class Line {
private Point from;
private Point to;
public Line(Point from, Point to) {
super();
this.from = from;
this.to = to;
}
public Point getFrom() {
return from;
}
public void setFrom(Point from) {
this.from = from;
}
public Point getTo() {
return to;
}
public void setTo(Point to) {
this.to = to;
}
}
三维线:
package kpi.ua.shapes;
public class Line3D {
private Point3D from;
private Point3D to;
public Line3D() {
super();
}
public Line3D(Point3D from, Point3D to) {
super();
this.from = from;
this.to = to;
}
public Point3D getFrom() {
return from;
}
public void setFrom(Point3D from) {
this.from = from;
}
public Point3D getTo() {
return to;
}
public void setTo(Point3D to) {
this.to = to;
}
public Line get2DVision() {
return new Line(from.get2DVision(), to.get2DVision());
}
}
要点:
package kpi.ua.shapes;
public class Point {
protected Double x;
protected Double y;
public Point() {
}
public Point(Double x, Double y) {
this.x = x;
this.y = y;
}
public Double getX() {
return x;
}
public void setX(Double x) {
this.x = x;
}
public Double getY() {
return y;
}
public void setY(Double y) {
this.y = y;
}
}
点三维:
package kpi.ua.shapes;
public class Point3D extends Point {
private Double z;
public Point3D(Double x, Double y, Double z) {
super(x, y);
this.z = z;
}
public Double getZ() {
return z;
}
public void setZ(Double z) {
this.z = z;
}
/**Èçîìåòðèÿ
* @return
*/
public Point get2DVision() {
Double cx=(1.0/Math.sqrt(6))*(Math.sqrt(3)*this.x-Math.sqrt(3)*this.z);
Double cy=(1.0/Math.sqrt(6))*(Math.sqrt(2)*this.x-Math.sqrt(2)*this.y+Math.sqrt(2)*this.z);
return new Point(cx, cy);
}
@Override
public String toString() {
return "Point3D [z=" + z + ", x=" + x + ", y=" + y + "]";
}
}
基于布齐尔曲线的表面:
package kpi.ua.shapes;
import java.awt.Graphics2D;
import java.util.LinkedList;
import java.util.List;
import kpi.ua.util.ControlUtil;
import kpi.ua.util.GraphicUtil;
public class SurfaceBasedOnBuzierCurve {
private final static Double DEFAULT_STEP_BY_T = 0.05;
private final static Double DEFAULT_Q = 1.0;
private final static Double DEFAULT_STEP_BY_FI = 0.15;
private BezierCurve movingCurve;
private List<Point3D> buzierPoints;
public SurfaceBasedOnBuzierCurve() {
refreshBuzierCurve();
}
public List<Point3D> getBuzierPoints() {
return buzierPoints;
}
public void setConePoints(List<Point3D> buzierPoints) {
this.buzierPoints = buzierPoints;
}
public void calcBuzierPoints() {
this.buzierPoints = new LinkedList<Point3D>();
Double q = DEFAULT_Q;
Point movingPoint;
for(double fi=0.0;fi<Math.PI*2;fi+=DEFAULT_STEP_BY_FI){
for(double t=0.0;t<=1.0;t+=DEFAULT_STEP_BY_T){
movingPoint=this.movingCurve.getValue(t);
Point3D firstPoint =getSurfacePoint(movingPoint, movingPoint, q, fi);
if(t+DEFAULT_STEP_BY_T<=1){
movingPoint=this.movingCurve.getValue(t+DEFAULT_STEP_BY_T);
Point3D secondPoint =getSurfacePoint(movingPoint, movingPoint, q, fi);
Point3D thirdPoint=getSurfacePoint(movingPoint, movingPoint, q, fi+DEFAULT_STEP_BY_FI);
buzierPoints.add(firstPoint);
buzierPoints.add(thirdPoint);
buzierPoints.add(secondPoint);
}
}
}
}
/**
* Gets 3DPoint on surface via roating line
*
* @param from
* @param to
* @param q
* @param fi
* @return
*/
public Point3D getSurfacePoint(Point from, Point to, Double q, Double fi) {
Double x = from.getX() + (to.getX() - from.getX()) * q;
Double y = (from.getY() + (to.getY() - from.getY()) * q) * Math.cos(fi);
Double z = (from.getY() + (to.getY() - from.getY()) * q) * Math.sin(fi);
return new Point3D(x, y, z);
}
public void drawBuzierSurface(Graphics2D gr) {
if (buzierPoints == null)
calcBuzierPoints();
GraphicUtil.drawTriangulation(gr, buzierPoints);
}
public void refreshBuzierCurve(){
LinkedList<Point> allPoints = new LinkedList<>();
allPoints.add(new Point(ControlUtil.BUZIER_FIRST_X, ControlUtil.BUZIER_FIRST_Y));
allPoints.add(new Point(ControlUtil.BUZIER_SECOND_X, ControlUtil.BUZIER_SECOND_Y));
allPoints.add(new Point(ControlUtil.BUZIER_THIRD_X, ControlUtil.BUZIER_THIRD_Y));
allPoints.add(new Point(ControlUtil.BUZIER_FOURTH_X, ControlUtil.BUZIER_FOURTH_X));
allPoints.add(new Point(ControlUtil.BUZIER_FIFTH_X, ControlUtil.BUZIER_FIFTH_X));
this.movingCurve = new BezierCurve(allPoints);
}
}
控制实用程序:
package kpi.ua.util;
import kpi.ua.shapes.Point;
import kpi.ua.shapes.Point3D;
public class ControlUtil {
public static Double scaleX=1.0;
public static Double scaleY=1.0;
public static Double scaleZ=1.0;
public static long serialVersionUID = 45L;
public static Double AXIS_LENGTH = 200.0;
public static Point CENTER_AXISES = new Point(300.0, 200.0);
public static Point3D AXIS_X;
public static Point3D AXIS_Y;
public static Point3D AXIS_Z;
public static Double CONE_PARAMETR_A=4.0;
public static Double CONE_PARAMETR_B=6.0;
public static Double CONE_PARAMETR_C=5.0;
public static Double CONE_START_RADIOUS=25.0;
public static Double STEP_BY_FI=0.2;
public static Boolean isDrawCone=false;
// allPoints.add(new Point(30.0, 10.0));
// allPoints.add(new Point(300.0, 210.0));
// allPoints.add(new Point(100.0, 200.0));
// allPoints.add(new Complex((double) 55.0, (double) 251.0));
// allPoints.add(new Complex((double) 155.0, (double) 300.0));
public static Double BUZIER_FIRST_X=30.0;
public static Double BUZIER_FIRST_Y=10.0;
public static Double BUZIER_SECOND_X=-150.0;
public static Double BUZIER_SECOND_Y=110.0;
public static Double BUZIER_THIRD_X=100.0;
public static Double BUZIER_THIRD_Y=200.0;
public static Double BUZIER_FOURTH_X=55.0;
public static Double BUZIER_FOURTH_Y=251.0;
public static Double BUZIER_FIFTH_X=155.0;
public static Double BUZIER_FIFTH_Y=300.0;
static{
AXIS_X=new Point3D(AXIS_LENGTH, 0.0 ,0.0);
AXIS_Y=new Point3D(0.0,AXIS_LENGTH, 0.0);
AXIS_Z=new Point3D(0.0, 0.0, AXIS_LENGTH);
}
}
图形实用程序:
package kpi.ua.util;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.util.Iterator;
import java.util.List;
import kpi.ua.shapes.Line;
import kpi.ua.shapes.Line3D;
import kpi.ua.shapes.Point3D;
public class GraphicUtil{
public static void drawAxis(Graphics2D gr){
gr.setColor(Color.RED);
drawLine(gr,new Line3D(new Point3D(0.0,0.0,0.0),ControlUtil.AXIS_X));
gr.setColor(Color.WHITE);
gr.drawString("x", ControlUtil.CENTER_AXISES.getX().intValue()+ControlUtil.AXIS_X.get2DVision().getX().intValue()+5,
ControlUtil.CENTER_AXISES.getY().intValue()-ControlUtil.AXIS_X.get2DVision().getY().intValue());
gr.setColor(Color.RED);
drawLine(gr,new Line3D(new Point3D(0.0,0.0,0.0),ControlUtil.AXIS_Y));
gr.setColor(Color.WHITE);
gr.drawString("y", ControlUtil.CENTER_AXISES.getX().intValue()+ControlUtil.AXIS_Y.get2DVision().getX().intValue()+5,
ControlUtil.CENTER_AXISES.getY().intValue()-ControlUtil.AXIS_Y.get2DVision().getY().intValue());
gr.setColor(Color.RED);
drawLine(gr,new Line3D(new Point3D(0.0,0.0,0.0),ControlUtil.AXIS_Z));
gr.setColor(Color.WHITE);
gr.drawString("z", ControlUtil.CENTER_AXISES.getX().intValue()+ControlUtil.AXIS_Z.get2DVision().getX().intValue()+5,
ControlUtil.CENTER_AXISES.getY().intValue()-ControlUtil.AXIS_Z.get2DVision().getY().intValue());
}
public static void moveAroundZ(Double fi,List<Point3D> shape){
Double x;
Double y;
if(shape!=null){
for(Point3D point:shape){
x=point.getX()*Math.cos(fi)+point.getY()*Math.sin(fi);
y=point.getX()*Math.sin(fi)-point.getY()*Math.cos(fi);
point.setX(x);
point.setY(y);
}
}
}
public static void moveAroundX(Double fi,List<Point3D> shape){
Double y;
Double z;
if(shape!=null){
for(Point3D point:shape){
y=-point.getY()*Math.cos(fi)-point.getZ()*Math.sin(fi);
z=-point.getY()*Math.sin(fi)+point.getZ()*Math.cos(fi);
point.setY(y);
point.setZ(z);
}
}
}
public static void moveAroundY(Double fi,List<Point3D> shape){
Double x;
Double z;
if(shape!=null){
for(Point3D point:shape){
x=point.getX()*Math.cos(fi)+point.getZ()*Math.sin(fi);
z=-point.getX()*Math.sin(fi)+point.getZ()*Math.cos(fi);
point.setX(x);
point.setZ(z);
}
}
}
public static void drawLine(Graphics2D gr,Line3D line3D){
line3D.getFrom().setX(ControlUtil.scaleX*line3D.getFrom().getX());
line3D.getFrom().setY(ControlUtil.scaleY*line3D.getFrom().getY());
line3D.getFrom().setZ(ControlUtil.scaleZ*line3D.getFrom().getZ());
line3D.getTo().setX(ControlUtil.scaleX*line3D.getTo().getX());
line3D.getTo().setY(ControlUtil.scaleY*line3D.getTo().getY());
line3D.getTo().setZ(ControlUtil.scaleZ*line3D.getTo().getZ());
Line line=line3D.get2DVision();
gr.drawLine((int)Math.round(ControlUtil.CENTER_AXISES.getX()+line.getFrom().getX()), (int)Math.round(ControlUtil.CENTER_AXISES.getY()-line.getFrom().getY()), (int)Math.round(ControlUtil.CENTER_AXISES.getX()+line.getTo().getX()),(int) Math.round(ControlUtil.CENTER_AXISES.getY()-line.getTo().getY()));
}
public static void drawTriangulation(Graphics2D gr,List<Point3D> shape){
if(shape==null)
return;
Iterator<Point3D> iter=shape.iterator();
Point3D from=null;
Point3D to=null;
while(iter.hasNext()){
from=iter.next();
if(iter.hasNext()){
to=iter.next();
GraphicUtil.drawLine(gr, new Line3D(from,to));
if(iter.hasNext()){
from=iter.next();
GraphicUtil.drawLine(gr, new Line3D(from,to));
}
}
}
}
}
关于java - 使用哪个框架从样条线挤出 3D 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27094318/
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我试图用这种形式简单地获取数字 28 integer+space+integer+integer+space+integer我试过这个正则表达式 \\s\\d\\d\\s 但我得到了两个数字11 和
最近一直在学习D语言。我一直对运行时感到困惑。 从我能收集到的关于它的信息中,(这不是很多)我知道它是一种有助于 D 的一些特性的运行时。像垃圾收集一样,它与您自己的程序一起运行。但是既然 D 是编译
想问一下这两个正则表达式有区别吗? \d\d\d 与 \d{3} 我已经在我的本地机器上使用 Java 和 Windows 操作系统对此进行了测试,两者都工作正常并且结果相同。但是,当在 linux
我正在学习 Go,而且我坚持使用 Go 之旅(exercise-stringer.go:https://tour.golang.org/methods/7)。 这是一些代码: type IPAddr
我在Java正则表达式中发现了一段令我困惑的代码: Pattern.compile( "J.*\\d[0-35-9]-\\d\\d-\\d\\d" ); 要编译的字符串是: String string
我在 ruby 代码上偶然发现了这个。我知道\d{4})\/(\d\d)\/(\d\d)\/(.*)/是什么意思,但是\1-\2-\3-\4 是什么意思? 最佳答案 \1-\2-\3-\4 是 b
我一直在努力解决这个问题,这让我很恼火。我了解 D 运行时库。它是什么,它做什么。我也明白你可以在没有它的情况下编译 D 应用程序。就像 XoMB 所做的那样。好吧,XoMB 定义了自己的运行时,但是
我有两个列表列表,子列表代表路径。我想找到所有路径。 List> pathList1 List> pathList2 当然是天真的解决方案: List> result = new ArrayList>
我需要使用 Regex 格式化一个字符串,该字符串包含数字、字母 a-z 和 A-Z,同时还包含破折号和空格。 从用户输入我有02-219 8 53 24 输出应该是022 198 53 24 我正在
目标是达到与this C++ example相同的效果: 避免创建临时文件。我曾尝试将 C++ 示例翻译为 D,但没有成功。我也尝试过不同的方法。 import std.datetime : benc
tl;dr:你好吗perfect forwarding在 D? 该链接有一个很好的解释,但例如,假设我有这个方法: void foo(T)(in int a, out int b, ref int c
有什么方法可以在 D 中使用abstract auto 函数吗? 如果我声明一个类如下: class MyClass { abstract auto foo(); } 我收到以下错误: mai
有没有人为内存中重叠的数组切片实现交集?算法在没有重叠时返回 []。 当 pretty-print (使用重叠缩进)内存中重叠的数组切片时,我想要这个。 最佳答案 如果您确定它们是数组,那么只需取 p
我已经开始学习 D,但我在使用 Andrei Alexandrescu 所著的 The D Programming Language 一书中提供的示例时遇到了一些麻烦。由于 int 和 ulong 类
如何创建一个不可变的类? 我的目标是创建一个实例始终不可变的类。现在我只是用不可变的方法和构造函数创建了一个“可变”类。我将其称为 mData,m 表示可变。然后我创建一个别名 alias immut
不久前我买了《The D Programming Language》。好书,很有教育意义。但是,我在尝试编译书中列出的语言功能时遇到了麻烦:扩展函数。 在这本书中,Andrei 写了任何可以像这样调用
我在 D http://www.digitalmars.com/d/2.0/lazy-evaluation.html 中找到了函数参数的惰性求值示例 我想知道如何在 D 中实现可能的无限数据结构,就像
这个问题在这里已经有了答案: 12 年前关闭。 Possible Duplicate: Could anyone explain these undefined behaviors (i = i++
当前是否可以跨模块扫描/查询/迭代具有某些属性的所有函数(或类)? 例如: source/packageA/something.d: @sillyWalk(10) void doSomething()
我是一名优秀的程序员,十分优秀!