maxminmethod.htm
来自「电脑图学(Computer Graphics)是资料结构、演算法与数学的应用」· HTM 代码 · 共 164 行
HTM
164 行
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" href="css/stdlayout.css" type="text/css">
<link rel="stylesheet" href="css/print.css" type="text/css">
<meta content="text/html; charset=gb2312" http-equiv="content-type">
<title>最大最小法</title>
</head>
<body>
<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>
<h1><a href="ComputerGraphics.htm">Computer Graphics: 最大最小法</a></h1>
在 <a href="FunctionGraphic.htm">函式图形绘制</a> 的范例中,发现到有一些座标点必须是被遮盖住,而不应被绘制出来的。<br>
<br>
在处理隐藏面的问题时,必须根据绘制图形来决定不同的方法,对于单纯的座标点绘制,可以使用简单的最大最小法来让被遮盖的座标点不被绘制。<br>
<br>
最大最小法的原理很简单,绘制时必须从最接近我们的点开始绘制,也就是由最大的Z座标点开始绘制;最大最小点是根据Y座标的值来决定哪些点应该被绘制,假设绘制图形时是使用以下的回圈: <br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;"> for(z = 200; z >= -200; z-=10) { </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;"> for(x = -200; x <= 200; x++) { </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;"> //计算座标并绘点 </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;"> .... </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;"> } </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;"> }</span><br>
</div>
<br>
<br>
假设前三次绘图在Y的坡度上是渐增的,如下所示:<br>
<span class="postbody"></span><img style="width: 379px; height: 208px;" alt="" src="images/maxMinMethod-1.jpg"><br>
<br>
必须记录每一个x位置上的ymax与ymin,如果在第四次绘制时某些位置上的Y坡度是下降的,则那些位置上的Y必然是位于ymax与ymin之间,此时这些点可以不绘制,如下图所示: <br>
<img style="width: 516px; height: 212px;" alt="" src="images/maxMinMethod-2.jpg"><br>
<br>
<br>
记得在一开始必须将ymax设定为最小的Y值,ymin设定为最大的Y值;以下是将函式绘图中的范例应用最大最小法绘制的方法与结果: <br>
<ul>
<li> MaxMinMethodDemo.java
</li>
</ul>
<pre>package onlyfun.caterpillar;<br> <br>import java.awt.Color;<br>import java.awt.Graphics;<br>import javax.swing.JApplet;<br> <br>public class MaxMinMethodDemo extends JApplet {<br> private int orgX;<br> private int orgY;<br> private int[] ymax, ymin;<br> <br> public void init() {<br> super.init();<br> setBackground(Color.black);<br> orgX = (int)getSize().width /2;<br> orgY = (int) (getSize().height / 2);<br> ymax = new int[600]; <br> ymin = new int[600]; <br> }<br> <br> public void paint(Graphics g) {<br> g.setColor(Color.yellow);<br><br> // 重置最大最小点<br> for(int i = 0; i < 600; i++) { <br> ymax[i] = 0; <br> ymin[i] = 600; <br> }<br> <br> // 从斜角绘制<br> // 绕 x 轴转 30 度,绕 y 轴转 -30 度<br> double angleX = Math.toRadians(30);<br> double angleY = Math.toRadians(-30);<br><br> for(int z = 200; z >= -200; z-=10) { <br> for(int x = -200; x <= 200; x++) {<br> double y = 30*(Math.cos(<br> Math.toRadians(<br> Math.sqrt(x*x+z*z))) <br> + Math.cos(<br> Math.toRadians(3 *<br> Math.sqrt(x*x+z*z))); <br> <br> // 立体旋转,从斜角绘制,调整绘图中心至视窗中心<br> int pointX = (int) (orgX + x*Math.cos(angleY) + <br> z*Math.sin(angleY));<br> int pointY = (int) (orgY - (y*Math.cos(angleX) - <br> (-x*Math.sin(angleY) + <br> z*Math.cos(angleY)) * <br> Math.sin(angleX))); <br><br> // 最大最小法 <br> if(pointY < ymin[pointX]) { <br> ymin[pointX] = pointY; <br> g.drawLine(pointX, pointY, pointX, pointY);<br> } <br><br> if(pointY > ymax[pointX]) { <br> ymax[pointX] = pointY; <br> g.drawLine(pointX, pointY, pointX, pointY); <br> } <br> } <br> }<br> }<br>}</pre>
<br>
<br>
<img style="width: 607px; height: 469px;" alt="" src="images/maxMinMethod-3.jpg"><br>
<br>
<br>
<br>
</body>
</html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?